Tsql 选择列值唯一的所有行

Tsql 选择列值唯一的所有行,tsql,sql-server-2012,distinct-values,Tsql,Sql Server 2012,Distinct Values,有一个表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 * f

有一个表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
选择*
从t
哪里
n00 n01和n00 n02以及。。。和n00 n99
n01 n02和n01 n03以及。。。和n01 n99
n02 n03和n02 n04以及。。。和n02 n99
...
以及n97 n98和n97 n99
和n98 n99
。。。但用“更聪明”的地方挡


欢迎任何提示。

使用交叉应用和少量XML的更动态的方法。我应该补充一点,UNPIVOT的性能会更好,但是这种方法的性能非常好,而且您不必识别所有字段

您会注意到我添加了一个ID字段。如果不存在,则可以从交叉应用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部分将生成以下内容


您也可以使用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)

约翰,我不明白你的答案,但结果是正确的。我想我现在需要去SQL crèche。我选择Tyron78的答案而不是你的答案,因为它不需要任何XML转换。不过,我还是很惊讶。@xpil哪个答案最适合你。将XML部分放在后口袋中。我发现它对于动态地将数据转换为EAV(实体属性值)结构非常有用。我更喜欢您的解决方案,因为它不涉及XML的内部转换。但两者都返回正确的结果。