SQL-Server查询以选择多个列的最后和先前信息

时间:2018-10-15 19:49:07

标签: sql sql-server

查看Stackoverflow之后,我找不到解决此问题的方法。

我正在使用此查询:

SELECT * 
FROM(
     SELECT DISTINCT *  
     FROM Table_01
     ORDER BY ID, StartDate
     UNION ALL(
     SELECT DISTINCT * FROM Table_02
     ORDER BY ID, StartDate
    )
    UNION ALL (...
    ) a ORDER BY a.ID, a.StartDate

我得到了这样的信息,对于每个ID,我都希望保留上一个和上一个日期以及其他列,以记录历史记录

+------+------------+-----------+-------+-------+
|  ID  | StartDate  | EndDate   | Value | rate   |
+------+------------+-----------+-------+-------+
|   1  | 2018-06-29 |2018-10-22 |   15  | 77.2   |
|   1  | 2018-04-28 |2018-06-21 |   23  | 55.3   |
|   1  | 2018-02-24 |2018-04-15 |   41  | 44.3   |
|   1  | 2017-06-29 |2017-11-29 |   55  | 44.1   |
|   2  | 2018-07-29 |2018-11-22 |   15  | 106.1  |
|   2  | 2018-03-28 |2018-07-21 |   23  | 10.8   |
|   2  | 2017-12-28 |2018-03-28 |   22  | 11.0   |
|   3  | 2017-09-28 |2018-01-28 |   11  | 87.09  |
|   3  | 2017-06-27 |2018-09-28 |   58  | 100    |
|  ... |    ...     |    ...    |  ...  | ...    |
+------+------------+-----------+-------+--------+

我想保留下一张表,以保留先前的信息

+------+------------+-----------+------------+-----------+-------+--------+-------+--------+
|  ID  | StartDate  | EndDate   | StartDateP | EndDateP  | Value | rate   | ValueP| rateP  |
+------+------------+------------+-----------+-----------+-------+--------+-------+--------+
|   1  | 2018-06-29 |2018-10-22 | 2018-04-28 |2018-06-21 |   15  | 77.2   |   23  | 55.3   |
|   2  | 2018-07-29 |2018-11-22 | 2018-03-28 |2018-07-21 |   15  | 106.1  |   23  | 10.8   |
|   3  | 2017-09-28 |2018-01-28 | 2017-06-27 |2018-09-28 |   11  | 87.09  |   58  | 100    |
|  ... |    ...     |    ...    |    ...     |    ...    |  ...  | ...    |  ...  | ...    |
+------+------------+-----------+------------+-----------+-------+--------+-------+--------+

2 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,那么您希望将具有最新开始日期的行与之前具有开始日期的行结合起来吗?这可能会解决问题

WITH results AS
(
  SELECT *, ROW_NUMBER() OVER(PARTITION BY ID ORDER BY StartDate DESC) r
  FROM (
    -- start of your original query
    SELECT DISTINCT *
    FROM Table_01
    ORDER BY ID, StartDate

    UNION ALL

    (
       SELECT DISTINCT *
       FROM Table_02
       ORDER BY ID, StartDate
    )

    UNION ALL

    (...) a
    ORDER BY a.ID, a.StartDate

    -- end of your original query
  )
)
SELECT 
   r1.id, r1.startDate, r2.enddate, 
   r2.startDate startDateP, r2.enddate enddateP, 
   r1.value, r1.rate, 
   r2.value valueP, r2.rate rateP 
FROM results r1
LEFT JOIN results r2 ON r2.id = r1.id AND r2.r = 2
WHERE r1.r = 1

答案 1 :(得分:0)

另一种选择是将Row_Number()与条件聚合一起使用

示例

Select ID 
      ,StartDate  = max(case when RN=1 then StartDate end)
      ,EndDate    = max(case when RN=1 then EndDate end)
      ,StartDateP = max(case when RN=2 then StartDate end)
      ,EndDateP   = max(case when RN=2 then EndDate end)
      ,Value      = max(case when RN=1 then Value end)
      ,Rate       = max(case when RN=1 then Rate end)
      ,ValueP     = max(case when RN=2 then Value end)
      ,RateP      = max(case when RN=2 then Rate end)
 From  (
        Select *
              ,RN = Row_Number() over (Partition By ID Order by EndDate Desc) 
         From  YourTable
       ) A
 Group By ID

返回

enter image description here