sql – 在符合条件的行之后选择三行

我们有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的三次调用为您提供原始集合中每个城市之后的前三个(或更少)目的地.接下来的最后一步是过滤掉起点不是华沙的行.

点赞