如何在

时间:2017-10-25 08:58:01

标签: sql-server date group-by

我经常搜索,但没有发现任何与我的查询相关的内容。我想要的是我想将下一行的日期添加到后一行。例如:

cusnbr name  loadnumber  date
 1      A       10       20100101
 1      A       20       20110101
 1      B       30       20120101  *
 2      C       40       20130101
 2      D       50       20140101  *

我看到的是下面的输出:

cusnbr name  loadnumber  date
 1      A       20       20120101
 2      C       40       20140101

*的日期,但根据特定客户的更改名称,从之前的记录。他们是百万客户,这只是我把它放在这里的一个例子。我应该遵循什么方法或任何可以帮助我的代码都会很棒!!

1 个答案:

答案 0 :(得分:0)

这有点奇怪的查询,但我认为这是你想要的?

首先,我制作一份测试数据的临时副本:

DECLARE @table TABLE (cusnbr INT, name CHAR(1), loadnumber INT, [date] DATE);
INSERT INTO @table SELECT 1, 'A', 10, '20100101';
INSERT INTO @table SELECT 1, 'A', 20, '20110101';
INSERT INTO @table SELECT 1, 'B', 30, '20120101';
INSERT INTO @table SELECT 2, 'C', 40, '20130101';
INSERT INTO @table SELECT 2, 'D', 50, '20140101';

然后我用它来确定哪些客户更改了名称,以及您需要的所有其他指标:

WITH Customers AS (
    SELECT
        cusnbr,
        MIN(name) AS old_name,
        MAX(name) AS new_name
    FROM
        @table
    GROUP BY
        cusnbr
    HAVING
        COUNT(DISTINCT name) > 1),
LoadNumbers AS (
    SELECT
        cusnbr,
        name,
        MAX(loadnumber) AS loadnumber
    FROM
        @table
    GROUP BY
        cusnbr,
        name),
Groups AS (
    SELECT
        name,
        MAX([date]) AS [date],
        DENSE_RANK() OVER (ORDER BY name) AS id
    FROM
        @table
    GROUP BY
        name)
SELECT
    c.cusnbr,
    c.old_name,
    c.new_name,
    l.loadnumber,
    g2.[date]
FROM
    Customers c
    INNER JOIN Groups g1 ON g1.name = c.old_name
    INNER JOIN Groups g2 ON g2.id = g1.id + 1
    INNER JOIN LoadNumbers l ON l.cusnbr = c.cusnbr AND l.name = c.old_name;

结果是:

cusnbr  old_name    new_name    loadnumber  date
1       A           B           20          2012-01-01
2       C           D           40          2014-01-01

我添加了旧/新名称,以便更容易理解,但您可以删除不需要的名称?