查询的正确性

时间:2010-07-10 05:01:18

标签: sql-server

有兴趣知道我的查询是否正确,问题是here发布的。我怀疑如果我写了一篇完美的文章,我想问你们哪里可以改进我的代码。

注意:我不想用很多代码来填充这个地方,非常简短。谢谢。

SELECT a.BookingId                         AS BookingId,
       CAST(b.TransactionDateTime AS DATE) AS TransactionDate
FROM   TC33_AuditTrial A
       JOIN TC33_AuditTrial b
       ON     a.AuditId                    = b.AuditId
WHERE  a.TransactionType                   = 'S'
AND    CAST(a.TransactionDateTime AS DATE) =
       (SELECT CAST(b.TransactionDateTime AS DATE)
       FROM    TC33_AuditTrial b
       WHERE   b.BookingId = a.BookingId
       AND     b.AuditId   =
               (SELECT MAX(b.AuditId)
               FROM    TC33_AuditTrial b
               WHERE   a.BookingId       = b.BookingId
               AND     b.TransactionType = 'R'
               )
       )
AND    a.TransactionValue =
       (SELECT SUM(b.TransactionValue)
       FROM    TC33_AuditTrial b
       WHERE   a.BookingId       = b.BookingId
       AND     b.TransactionType = 'R'
       )

2 个答案:

答案 0 :(得分:3)

<强>已取消删除

我原来的回答是

SELECT BookingId, CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate
FROM TC33_AuditTrial
GROUP BY BookingId, CONVERT(VARCHAR(8), TransactionDateTime, 112)
HAVING 
SUM(CASE TransactionType WHEN 'S' THEN TransactionValue END) <= 
SUM(CASE TransactionType WHEN 'R' THEN TransactionValue END)
ORDER BY BookingID

我很满意,因为它只是通过数据一次。

然后我注意到规范的更新位,它必须限制在包含该预订条目的第一个日期。我能想到的唯一方法是添加一个子查询,这会大大增加查询的成本。

令人沮丧的是,我希望将结果限制在每个BookingId的第一天,我已经通过BookingId,Day

进行分组

感觉就像在没有子查询的情况下可能有一些聪明的方法来获得这个限制但是如果是这样的话到目前为止它已经躲过我了!

我只是设法让'OVER'工作。在竞赛结束之前我不会发布这个答案,除非它与8kb发布的查询计划具有完全相同的查询计划

WITH X AS
(
SELECT   BookingId,
         RANK() OVER(PARTITION BY BookingId ORDER BY CONVERT(VARCHAR(8), TransactionDateTime, 112)) AS Rnk,
         CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate,
         SUM(CASE TransactionType WHEN 'S' THEN TransactionValue END) AS S,
         SUM(CASE TransactionType WHEN 'R' THEN TransactionValue END) AS R
FROM     TC33_AuditTrial t1
GROUP BY BookingId,
         CONVERT(VARCHAR(8), TransactionDateTime, 112)
)

SELECT BookingId, TransactionDate
FROM X
WHERE Rnk = 1 AND S<=R
ORDER BY BookingID

答案 1 :(得分:1)

也不得不跳进去......

SELECT
  BookingID,
  CONVERT(VARCHAR(8), TransactionDateTime, 112) AS TransactionDate
FROM (
SELECT 
  BookingID,
  TransactionDateTime,
  COALESCE(pvt.S,0) AS Sale,
  COALESCE(pvt.R,0) AS Receipt,
  ROW_NUMBER() OVER (
    PARTITION BY BookingID ORDER BY (TransactionDateTime)) AS Rn
FROM (
  SELECT
    BookingID,
    DATEADD(DD, DATEDIFF(DD,0,TransactionDateTime), 0) AS TransactionDateTime,
    TransactionType,
    TransactionValue
  FROM TC33_AuditTrial
  ) t
PIVOT (
  SUM(TransactionValue)
  FOR TransactionType IN (S,R)
) AS pvt
) t2
WHERE Receipt >= Sale
AND Rn = 1