假设我有这段代码:
DECLARE @IncludeDuplicateAddressIDs tinyint
-- Value of @IncludeDuplicateAddressIDs set here ! --
IF(@IncludeDuplicateAddressIDs = 1)
SELECT AddressIds FROM RTS.ADDRESSES
ELSE
SELECT DISTINCT(AddressIds) FROM RTS.ADDRESSES
我可以将两个SELECT
语句组合成一个吗?也就是说,只使用一个SELECT
,我会显示所有的AddressID,或者只显示其中一个?
答案 0 :(得分:2)
你可以这样做:
SELECT AddressIds FROM RTS.ADDRESSES WHERE @IncludeDuplicateAddressIDs = 1
UNION ALL
SELECT DISTINCT(AddressIds) FROM RTS.ADDRESSES WHERE @IncludeDuplicateAddressIDs <> 1
由于WHERE
子句是互斥的,因此只有UNION
个查询中的一个会返回一些行;另一个查询将不返回任何内容。
答案 1 :(得分:1)
如果表包含唯一列,则可以使用此选项(假设唯一列的名称为Id
):
DECLARE @IncludeDuplicateAddressIDs tinyint = 1
SELECT AddressIds
FROM RTS.ADDRESSES
GROUP BY CASE WHEN @IncludeDuplicateAddressIDs = 1
THEN Id ELSE AddressIds END, AddressIds
SQLFiddle上的演示
答案 2 :(得分:0)
您可以包含重复地址的数量。
SELECT AddressIDs, count(*) as cnt
FROM RTS.ADDRESSES
GROUP BY AdressIDs
答案 3 :(得分:0)
您可以使用sp_executesql动态sql将查询形成为字符串(并根据需要设置多个列),然后执行它:
DECLARE @IncludeDuplicateAddressIDs tinyint
DECLARE @Columns varchar(500);
IF(@IncludeDuplicateAddressIDs = 1) SET @Columns='AddressIds'
ELSE SET @Columns='DISTINCT(AddressIds)'
EXECUTE sp_executesql N'SELECT ' + @Columns + 'AddressIds FROM RTS.ADDRESSES';
答案 4 :(得分:0)
试试这个 -
DECLARE @IncludeDuplicateAddressIDs TINYINT
SELECT @IncludeDuplicateAddressIDs = 0
SELECT t.AddressIds
FROM (
SELECT
AddressIds
, cnt = ROW_NUMBER() OVER (PARTITION BY AddressIds ORDER BY AddressIds)
FROM RTS.ADDRESSES
) t
WHERE @IncludeDuplicateAddressIDs = 1
OR (@IncludeDuplicateAddressIDs != 1 AND cnt = 1)
在此查询中,未使用UNION或DISTINCT构造。因此,SQL可以生成更有效的查询计划。