多个字段的T-SQL条件

时间:2013-09-24 20:00:08

标签: sql sql-server tsql

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

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

- 或 -

如果IsPromoted列为true,则返回true。

   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 

有人能提出更好的方法吗?

2 个答案:

答案 0 :(得分: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)我想create an index on this computed column

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

答案 1 :(得分: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'