在单行中检索与MIN(日期)和MAX(日期)有关的列值

时间:2017-06-28 22:14:07

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

我的表格结构如下:

| 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(日期)相关的行,然后选择Max(日期)的行。

返回给我:

| 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查询方面相当新手,所以我不确定如何实现我想要的。任何帮助都会很棒。

1 个答案:

答案 0 :(得分: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来自哪一行。