中使用复合选择项这个问题最好用一个简单的例子来描述。在条款
为什么我不能这样做?
select (lastname + ', ' + firstname) as fullname
from people
where fullname = 'Bloggs, Joe'
相反,我必须这样做:
select (lastname + ', ' + firstname) as fullname
from people
where (lastname + ', ' + firstname) = 'Bloggs, Joe'
这气味对我不好。
查询越复杂,这个问题就越严重。
后续
这是基于从问题起源于现实世界的问题的一个更好的例子。
SELECT ClientID,
Name,
ContractStartDate,
ContractDetails.ContractLength,
DATEADD(MONTH, ContractDetails.ContractLength, ContractStartDate)
as ContractEndDate
FROM Clients
LEFT OUTER JOIN ContractDetails
ON Clients.ClientID = ContractDetails.ClientID
WHERE DATEADD(MONTH, ContractDetails.ContractLength, ContractStartDate)
> '2009-06-30'
我已经重写了查询以使用建议的嵌入视图。但它仍然包含重复 - 但这次是加入。
SELECT ClientID,
Name,
contractStartDate,
ContractDetails.ContractLength,
contractEndDate
FROM (
SELECT ClientID,
Name,
ContractStartDate,
DATEADD(MONTH, ContractDetails.ContractLength, contractStartdate)
AS contractEndDate
FROM Clients
LEFT OUTER JOIN ContractDetails
on Clients.ClientID = ContractDetails.ClientID
) myview
LEFT OUTER JOIN ContractDetails
on myview.ClientID = ContractDetails.ClientID
WHERE myview.ContractEndDate > '2009-06-30'
ORDER BY ClientID
该查询的点是找到所有活的客户端如在特定的时间点,在没有历史状态数据被保持(即计算从一个已知的合同开始日期和长度合同结束日期)。
任何人都可以想出一种消除这种重复的方法吗?
末次随访
罗宾天帮了我与我错过这里的关键,其实让我删除重复。然而,KM有一个观点,他说WHERE应该在嵌套视图上,而不是最终结果,这将需要重复部分语句(这是我试图避免的)。 在这种特殊情况下我可以逃脱它,因为我知道没有数百万的ContractDetails表中的记录,永远不会。
SELECT ClientID,
Name,
ContractStartDate,
myview.ContractLength,
ContractEndDate
FROM (
SELECT ClientID,
Name,
ContractStartDate,
DATEADD(MONTH, ContractDetails.ContractLength, ContractStartdate)
AS ContractEndDate,
ContractDetails.ContractLength as Length
FROM Clients
LEFT OUTER JOIN ContractDetails
on Clients.ClientID = ContractDetails.ClientID
) myview
WHERE myview.ContractEndDate > '2009-06-30'
ORDER BY ClientID
为什么downvote? – tomfanning 2009-08-12 15:52:28
将ContractLength添加到嵌套视图,并且不再需要在该视图之外执行联接。 – 2009-08-12 15:56:32