我正在尝试修改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
有人能提出更好的方法吗?
答案 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'