0

我被要求执行以下操作:“CycleStartDate 需要是上一个 BillDate 记录中的 BillDate。如果以前的记录不存在,您应该使用 DataTime 表中最近的 CycleEndDate”

CycleStartDate 和 CycleEndDate 是名为 DataTime 的表中的列

BillDate 是名为 BillingData 的表中的一列

这是 BillDate 值:

2012-07-27 00:00:00.000
2012-07-27 00:00:00.000
2012-08-27 00:00:00.000
2012-08-27 00:00:00.000
2012-09-28 00:00:00.000
2012-09-28 00:00:00.000
2012-10-26 00:00:00.000
2012-10-26 00:00:00.000
2012-11-27 00:00:00.000
2012-11-27 00:00:00.000
2012-12-27 00:00:00.000

我将如何根据要求设置 CycleStartDate 值?表 Datetime 和 BillingData 由一个名为 MeterID 的列连接。

4

2 回答 2

0

尝试类似的东西......

SELECT B.BillDate, 
       ISNULL(
              B2.BillDate, 
              (SELECT MAX(CycleEndDate) FROM DataTime DT WHERE DT.MeterID = B.MeterID)
             )  CycleStartDate 
    FROM BillingData B
    OUTER APPLY (
                 SELECT TOP 1 B2.BillDate 
                        FROM BillingData B2 
                        WHERE B2.MeterID = B.MeterID AND 
                              B2.BillingData < B.BillingData 
                        ORDER BY B2.BillingData DESC
                ) B2

我还有一个疑问……你需要拿SELECT MAX(CycleEndDate) FROM DataTime DT WHERE DT.MeterID = B.MeterID还是SELECT MAX(CycleEndDate) FROM DataTime DT WHERE DT.MeterID = B.MeterID AND DT.CycleEndDate < B.BillDate

但它可以在没有 OUTER APPLY 的情况下完成...

SELECT B.BillDate, 
       ISNULL(
              (SELECT MAX(B2.BillDate) 
                      FROM BillingData B2 
                      WHERE B2.MeterID = B.MeterID AND 
                            B2.BillingData < B.BillingData),

              (SELECT MAX(CycleEndDate) FROM DataTime DT WHERE DT.MeterID = B.MeterID)
             )  CycleStartDate 
       FROM BillingData B

我认为第二个版本可读性很强...对于 BillingData B 的每一行,寻找比当前和相同的最大BillDate( ) 小。如果不存在(,如果第一个不存在,那么它是,所以它转到 的第二部分),寻找最大的 from并返回它。MAX(B2.BillDate)BillDateMeterIDISNULLNULLISNULLCycleEndDateDataTimeMeterID

于 2013-08-12T17:42:52.737 回答
0

您可以使用该ROW_NUMBER()功能来抵消 a JOIN

SELECT a.BillDate, COALESCE(b.BillDate,c.CycleEndDate) 'CycleEndDate'
FROM (SELECT *,ROW_NUMBER() OVER (PARTITION BY MeterID ORDER BY BillDate DESC)'RowRank'
      FROM YourTable
     )a
LEFT JOIN (SELECT *,ROW_NUMBER() OVER (PARTITION BY MeterID ORDER BY BillDate DESC)'RowRank'
           FROM YourTable
           )b
      ON a.RowRank = b.RowRank - 1
      AND a.MeterID = b.MeterID
LEFT JOIN (SELECT MeterID,MAX(CycleEndDate)'CycleEndDate'
           FROM DataTime
           GROUP BY MeterID
          ) c
    ON a.MeterID = c.MeterID

PARTITION BY可能没有必要以及 中的标准MeterID,您的措辞对于应该升序还是降序JOIN有点混乱,因为它在最新记录之上将是从 DateTime 表中获取其日期的记录,删除使其成为从该表中获取其价值的最旧记录。ORDER BYDESC

于 2013-08-12T17:57:31.090 回答