【问题标题】:Retrieving column values pertaining to MIN(date) and MAX(date) in a single row在单行中检索与 MIN(date) 和 MAX(date) 相关的列值
【发布时间】:2017-06-28 22:14:06
【问题描述】:

我的表结构如下:

| TxnID | CardID | WhereName    | FirstName | LastName  | DateTimeOfxTxn        | .....|
----------------------------------------------------------------------------------------
|   1   |  1     | location1    |   test    | employee1 | 2017-06-28 00:01:00   |      |
|   2   |  1     | location2    |   test    | employee1 | 2017-06-28 00:02:00   |      |
|   3   |  2     | location1    |   test    | employee2 | 2017-06-28 00:03:00   |      |
|   4   |  1     | location3    |   test    | employee1 | 2017-06-28 00:03:30   |      |
|   5   |  1     | location1    |   test    | employee1 | 2017-06-28 00:04:00   |      |
|   6   |  2     | location2    |   test    | employee2 | 2017-06-28 00:05:00   |      |

现在,我有以下 SQL 查询:

WITH t1 AS (
 SELECT
    CardID,
    MIN(DateTimeOfTxn) AS mindate,
    MAX(DateTimeOfTxn) AS maxdate
  FROM ActivityDataView 
  where convert(datetime, floor(convert(float, DateTimeOfTxn))) = '06/28/2017'
  GROUP BY CardID
)

SELECT
  t2.CardID,
  t2.WhereName as Location,
  t2.FirstName + ' ' + t2.LastName as Name,
  t1.mindate,
  t1.maxdate
FROM ActivityDataView AS t2
JOIN t1
  ON (t2.CardID = t1.CardID AND t2.DateTimeOfTxn = t1.mindate)
  OR (t2.CardID = t1.CardID AND t2.DateTimeOfTxn = t1.maxdate)
order by CardID

该查询将选择与 Min(date) 相关的行,然后还选择 Max(date) 的行。

返回我:

| CardID | Location     | Name             | MinDate               | MaxDate
------------------------------------------------------------------------------------------
|  1     | location1    | test employee1   | 2017-06-28 00:01:00   | 2017-06-28 00:04:00  |
|  1     | location1    | test employee1   | 2017-06-28 00:01:00   | 2017-06-28 00:04:00  |
|  2     | location1    | test employee2   | 2017-06-28 00:03:00   | 2017-06-28 00:05:00  | 
|  2     | location2    | test employee2   | 2017-06-28 00:03:00   | 2017-06-28 00:05:00  |

我希望能够得到这个:

| CardID | Name             | MinDate               | MinLocation | MaxDate              | MaxLocation |
--------------------------------------------------------------------------------------------------------
|  1     | test employee1   | 2017-06-28 00:01:00   | location1   | 2017-06-28 00:04:00  | location 1  |
|  2     | test employee2   | 2017-06-28 00:03:00   | location1   | 2017-06-28 00:05:00  | location 2  |

我对 SQL 查询很陌生,所以我不确定如何实现我想要的。任何帮助都会很棒。

【问题讨论】:

    标签: sql sql-server sql-server-2008-r2


    【解决方案1】:

    您可以通过按 txntime 的升序和降序分配行号并聚合来做到这一点。

    SELECT CardID
    ,MAX(CASE WHEN RN_MIN=1 THEN WHERENAME END) AS MINLOCATION
    ,MAX(CASE WHEN RN_MIN=1 THEN DateTimeOfTxn END) AS MINDATE
    ,MAX(CASE WHEN RN_MAX=1 THEN WHERENAME END) AS MAXLOCATION
    ,MAX(CASE WHEN RN_MAX=1 THEN DateTimeOfTxn END) AS MAXDATE
    FROM (SELECT
           A.*
           ,ROW_NUMBER() OVER(PARTITION BY CardID ORDER BY DateTimeOfTxn) as RN_MIN
           ,ROW_NUMBER() OVER(PARTITION BY CardID ORDER BY DateTimeOfTxn DESC) as RN_MAX
           FROM ActivityDataView A
           WHERE cast(DateTimeOfTxn as date) = '2017-06-28'
         ) T
    WHERE 1 IN (RN_MIN,RN_MAX)
    GROUP BY CardID
    

    目前尚不清楚预期输出中的namelocation 来自哪一行。

    【讨论】:

    • 我很抱歉。 “位置”列不应存在于预期结果中——只有 MinLocation 和 MaxLocation 列。那是打错字了。 Name 只是 FirstName 和 LastName 的附加列,它与 CardID 相关联。
    • 所以名称来自最小行还是最大行?
    • 它可以是任何一个,因为名称将是相同的。但是您的查询看起来正是我需要的,可以从这里获取。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 2020-11-01
    • 2017-05-19
    • 2022-07-16
    • 2019-06-25
    • 1970-01-01
    • 2020-03-05
    相关资源
    最近更新 更多