选择行的最旧日期,并使用基于最旧日期或其他值的值创建新列

问题描述 投票:1回答:1

首先说明选择当前正在做什么。

Select reference, status, Valid, createDate, createdBy 
FROM 
(

select 1 as value, 'reference' reference, 'status' status, 'Valid' Valid, 'createDate' createDate, 'createdBy' createdBy

UNION ALL

SELECT 2 as value,

l.reference,

case l.number 
when 0 then 'not sent'
else 'sent'
end status,

l.Valid,
l.CreateDate,
l.CreatedBy
Convert(varchar 10), l.CreateDate, 111)CreateDate
From dbo.log l
where l.CreateDate > DATEADD(HOUR, -24, GETDATE())
) x 
ORDER BY x.CreateDate DESC

此数据的目的将由另一个过程用来生成文件。

因此,为什么我将列标题打印两次。

我的问题如下:

  • 我需要从选择中计算所有重复的参考文​​献
  • 我需要一个名为“ SendMethod”的新列
  • 然后从那些重复的引用中,我需要知道哪一行具有最早的CreateDate
  • 基于此,我需要此新列进行初始发送,如果它是这些重复行中最旧的CreateDate,则需要进行后续发送

我需要此新列作为选择的一部分。

因此,它可以一次生成所有数据,而不是通过多个结果集。

请参见下面的示例,其中包含一些虚拟数据的新列的外观。

Reference   Status   Valid  CreateDate       CreatedBy  SendMethod
Reference   Status   Valid  CreateDate       CreatedBy  SendMethod
1           Not sent    0   21/01/2020 12:00    John    initial send
2           Not sent    0   21/01/2020 12:03    Bob     initial send
3           Not sent    0   21/01/2020 12:05    Bob     initial send
4             Sent      1   19/01/2020 12:00    Jane    initial send
4             Sent      1   20/01/2020 12:00    Jane    subsequent send
4             Sent      1   21/01/2020 12:00    Jane    subsequent send
sql sql-server tsql
1个回答
0
投票

您可以使用“ row_number”按created进行排序,然后使用例如IIF来测试其是否是第一次出现引用。

这里是示例

WITH [log]
AS
(SELECT
        Reference
       ,Number
       ,Valid
       ,CAST(CreateDate AS DATETIME) CreateDate
       ,CreatedBy
    FROM (VALUES(1, 0, 0, '20200121 12:00', 'John')
    , (2, 0, 0, '20200121 12:03', 'Bob')
    , (3, 0, 0, '20200121 12:05', 'Bob')
    , (4, 1, 1, '20200119 12:00', 'Jane')
    , (4, 1, 1, '20200120 12:00', 'Jane')
    , (4, 1, 1, '20200121 12:00', 'Jane')

    ) a (Reference, Number, Valid, CreateDate, CreatedBy))

SELECT
    x.reference
   ,x.status
   ,x.Valid
   ,x.createDate
   ,x.createdBy
   ,x.SendMethod
FROM (SELECT
        1 AS value
       ,'reference' reference
       ,'status' status
       ,'Valid' Valid
       ,'createDate' createDate
       ,'createdBy' createdBy
       ,'SendMethod' SendMethod
    UNION ALL
    SELECT
        2 AS value
       ,STR(l.reference) reference
       ,CASE l.number
            WHEN 0 THEN 'not sent'
            ELSE 'sent'
        END status
       ,STR(l.Valid) Valid
       ,CONVERT(VARCHAR(10), l.CreateDate, 111) CreateDate
       ,l.CreatedBy
       /* This is the magic line */
       /* If the first instance of reference is found it will be given row_number 1 */
       ,IIF(ROW_NUMBER() OVER (PARTITION BY l.reference ORDER BY l.CreateDate) = 1, 'initial send', 'subsequent send') SendMethod

    FROM log l
where l.CreateDate > DATEADD(HOUR, -24, GETDATE())
) x
ORDER BY [value], X.CreateDate DESC
© www.soinside.com 2019 - 2024. All rights reserved.