表T包含列n00,n01,n01,...,n99,所有整数。
我需要从这个表中选择所有行,其中n00 ... n99值在每一行中都是唯一的。
列数较少的示例:
columns: n0, n1, n2
row 1: 10, 20, 30
row 2: 34, 45, 56
row 3: 12, 13, 12
row 4: 31, 65, 90
我需要select语句返回第1,2和4行而不是3(第3行包含12的非唯一值,因此将其过滤掉)。
有效地我需要实现这个:
select *
from t
where
n00 <> n01 and n00 <> n02 and ... and n00 <> n99
and n01 <> n02 and n01 <> n03 and ... and n01 <> n99
and n02 <> n03 and n02 <> n04 and ... and n02 <> n99
...
and n97 <> n98 and n97 <> n99
and n98 <> n99
...但是&#34;更聪明&#34;阻止。
欢迎任何提示。
答案 0 :(得分:2)
使用CROSS APPLY和一点XML的更动态的方法。我应该添加UNPIVOT会更高效,但这种方法的表现非常可观,而且你没有识别所有领域。
您会注意到我添加了ID字段。如果不存在,可以从CROSS APPLY C中删除。我添加了ID以证明可以从逻辑中排除其他字段。
Declare @YourTable table (id int,n0 int, n1 int, n2 int)
Insert Into @YourTable values
(1,10, 20, 30),
(2,34, 45, 56),
(3,12, 13, 12),
(4,31, 65, 90)
Select A.*
From @YourTable A
Cross Apply (Select XMLData=cast((Select A.* For XML Raw) as xml)) B
Cross Apply (
Select Cnt=count(*),Uniq=count(Distinct Value)
From (
Select ID = r.value('@id','int') -- case sensitive
,Item = attr.value('local-name(.)','varchar(100)')
,Value = attr.value('.','varchar(max)')
From B.XMLData.nodes('/row') as A(r)
Cross Apply A.r.nodes('./@*') AS B(attr)
Where attr.value('local-name(.)','varchar(100)') not in ('id','excludeotherfields') -- case sensitive
) U
) C
Where Cnt=Uniq
返回
id n0 n1 n2
1 10 20 30
2 34 45 56
4 31 65 90
如果它对可视化有帮助,那么XML部分将生成以下内容
答案 1 :(得分:2)
您也可以使用UNPIVOT:
DECLARE @t TABLE(n0 int, n1 int, n2 int);
INSERT INTO @t VALUES (10, 20, 30), (34, 45, 56), (12, 13, 12), (31, 65, 90);
WITH cteRows AS(
SELECT ROW_NUMBER() OVER (ORDER BY n0, n1, n2) rn, *
FROM @t
),
cteUP AS(
SELECT rn, rn_val
FROM cteRows
UNPIVOT(
rn_val FOR rn_vals IN(n0, n1, n2)
) up
),
cteFilter AS(
SELECT rn, rn_val, count(*) anz
FROM cteUP
GROUP BY rn, rn_val
HAVING count(*) > 1
)
SELECT *
FROM cteRows
WHERE rn NOT IN (SELECT rn FROM cteFilter)