1

我正在尝试修改 T-SQL 查询中的以下子句以匹配此条件:

如果支付表中存在有效记录,则返回true,否则返回false

- 或者 -

如果该IsPromoted列为真,则返回真。

   CASE
     WHEN (SELECT COUNT(*) AS Expr1
           FROM   dbo.Payments
           WHERE  ( EventId = dbo.Events.EventCode )
              AND ( DATEADD(day, DurationDays, PaymentReceived) 
                                                  > GETDATE() )) > 0 THEN 'true'
     WHEN ispromoted = 1 THEN 'true'
     ELSE 'false'
   END AS UpgradedState 

有人可以提出更好的方法来实现这一目标吗?

4

2 回答 2

4

我会使用EXISTS(SELECT ...)而不是(SELECT COUNT(*) FROM ...) > 0

CASE 
    WHEN IsPromoted = 1 THEN 'true' -- See Martin Smith's comment
    WHEN EXISTS(SELECT * FROM .... dbo.Payments ...) THEN 'true'
    ELSE 'false'
END

如果性能非常重要,那么我将测试解决方案:

1)我会创建一个计算列:

ALTER TABLE dbo.Payments
ADD ColumnA AS DATEADD(day, DurationDays, PaymentReceived);
GO

2)我会在这个计算列上创建一个索引

SET NUMERIC_ROUNDABORT  OFF;
SET ANSI_NULLS ON;
SET ANSI_PADDING ON;
SET ANSI_WARNINGS ON;
SET ARITHABORT ON;
SET CONCAT_NULL_YIELDS_NULL ON;
SET QUOTED_IDENTIFIER ON;
CREATE /*UNIQUE*/ INDEX IX_Payments_EventId_ColumnA
ON dbo.Payments(EventId, ColumnA);
GO

3)我会这样重写 EXISTS :

  CASE
     WHEN IsPromoted = 1 THEN 'true' -- See Martin Smith's comment
     WHEN EXITS(SELECT * FROM dbo.Payments
           WHERE EventId = dbo.Events.EventCode
           AND ColumnA > GETDATE()) THEN 'true'
     ELSE 'false'
  END

另外,我会尝试以下索引:

CREATE /*UNIQUE*/ INDEX IX_Payments_EventId_#_DurationDays_PaymentReceived
ON dbo.Payments(EventId)
INCLUDE(DurationDays, PaymentReceived);
GO
于 2013-09-24T20:10:36.483 回答
0

请注意,嵌套查询不是很快。如果您想提高性能,那么在 EventId = p.EventCode 上使用 dbo.Payments p 的 LEFT JOIN 会更快。以下 CASE 声明应该这样做。

 CASE
 WHEN (DATEADD(day, p.DurationDays, p.PaymentReceived) > GETDATE() ) > 0 THEN 'true'
 WHEN ispromoted = 1 THEN 'true'
 ELSE 'false'
于 2013-09-24T20:36:32.050 回答