我们有7个人在波兰旅行(;)).问题是他们访问华沙时最多可以找到他们访问过的三个城市.如果一个人两次访问华沙,它也被视为下一次旅行的起点.
例如,家伙1不仅有一个旅程 – 华沙,克拉科夫,华沙,格但斯克,还有华沙,格但斯克.
表A.
+------+-----------+-----+
| date | city | guy |
+------+-----------+-----+
| 2 | Warsaw | 1 |
| 4 | Cracow | 1 |
| 5 | Cracow | 2 |
| 6 | Bialystok | 3 |
| 7 | Warsaw | 1 |
| 8 | Gdansk | 1 |
| 10 | Warsaw | 5 |
| 12 | Cracow | 5 |
| 14 | Bialystok | 6 |
| 15 | Warsaw | 7 |
| 20 | Warsaw | 7 |
+------+-----------+-----+
所以最终的表格如下所示:
+-----------+-----------+-----------+-----------+
| Starting | 2nd dest. | 3th dest. | 4th dest. |
+-----------+-----------+-----------+-----------+
| Warsaw | Cracow | Warsaw | Gdansk |
| Warsaw | Gdansk | | |
| Warsaw | Cracow | | |
| Warsaw | Warsaw | | |
| Warsaw | | | |
+-----------+-----------+-----------+-----------+
问题是创建一个将自动从表A创建最终表的查询.
找到每个起点都没有问题,但我不知道如何找到每个第二个目的地.我似乎也必须有某种循环 – 这个人必须与起点相同,而第二个目的地的日期必须大于此确切起点的日期.
任何帮助解决这个问题将不胜感激. 😉
SQLFiddle有一些更多的示例条目数据–http://sqlfiddle.com/#!2/de0f1
上面的数据只是一个样本,解决方案需要处理更大的集合.
最佳答案 如果您使用的是SQL Server 2012或更高版本,则可以在
LEAD() analytic function的帮助下轻松实现
solve the problem:
WITH ThreeDestinations AS (
SELECT
*,
Destination2 = LEAD(city, 1) OVER (PARTITION BY guy ORDER BY date),
Destination3 = LEAD(city, 2) OVER (PARTITION BY guy ORDER BY date),
Destination4 = LEAD(city, 3) OVER (PARTITION BY guy ORDER BY date)
FROM
dbo.voyage
)
SELECT
StartingPoint = city,
Destination2,
Destination3,
Destination4
FROM
ThreeDestinations
WHERE
city = 'Warsaw'
ORDER BY
date
;
对LEAD的三次调用为您提供原始集合中每个城市之后的前三个(或更少)目的地.接下来的最后一步是过滤掉起点不是华沙的行.