如何仅在此现有SQL查询中显示唯一值

时间:2016-12-15 12:37:12

标签: sql sql-server sql-server-2016

我正在比较两个表(dbo.newdbo.old),如果前三列匹配且第四列匹配,则必须选择它。现在这显示了很多值,我只想显示column2的唯一值。这是我现在的代码:

SELECT dbo.new.[column1], dbo.new.[column2], dbo.new.[column3], dbo.new.[column4]
FROM dbo.new 
JOIN dbo.old ON dbo.new.[column1]=dbo.old.[column1] 
    AND dbo.new.[column2]=dbo.old.[column2] 
    AND dbo.new.[column3]=dbo.old.[column3]
WHERE [dbo].[new].[column4] <> [dbo].[old].[column4]

我开始的前两个表:

-----------------
| 1 | 1 | 1 | 1 |
-----------------
| 2 | 1 | 2 | 2 |
-----------------
| 3 | 3 | 3 | 3 |
-----------------
| 4 | 1 | 4 | 4 |
-----------------

-----------------
| 1 | 1 | 1 | 9 |
-----------------
| 2 | 1 | 2 | 9 |
-----------------
| 3 | 3 | 3 | 9 |
-----------------
| 4 | 1 | 4 | 9 |
-----------------

这是上述查询的结果:

-----------------
| 1 | 1 | 1 | 1 |
-----------------
| 2 | 1 | 2 | 2 |
-----------------
| 3 | 3 | 3 | 3 |
-----------------
| 4 | 1 | 4 | 4 |
-----------------
      ^ delete those duplicates

这就是我想要的结果:

-----------------
| 1 | 1 | 1 | 1 |
-----------------
| 3 | 3 | 3 | 3 |
-----------------

我尝试了许多内容,例如UNIQUEDISTINCT,但我无法找到解决方案。它甚至需要显示第一个值,只要它显示一行具有唯一编号。所以这也是正确的:

-----------------
| 4 | 1 | 4 | 4 |
-----------------
| 3 | 3 | 3 | 3 |
-----------------

2 个答案:

答案 0 :(得分:4)

over()中选择所需的顺序以获取正确的行。

SELECT TOP(1) WITH TIES 
   dbo.new.[column1], dbo.new.[column2], dbo.new.[column3], dbo.new.[column4] 
FROM dbo.new 
JOIN dbo.old ON dbo.new.[column1]=dbo.old.[column1] 
AND dbo.new.[column2]=dbo.old.[column2] 
AND dbo.new.[column3]=dbo.old.[column3]
where [dbo].[new].[column4] <> [dbo].[old].[column4]
ORDER BY row_number() over(partition by dbo.new.[column2] order by dbo.new.[column1])

快速演示,运行OK sql server 2014

create table dbo.new(
    column1 int,
    column2 int,
    column3 int,
    column4 int);
create table dbo.old(
    column1 int,
    column2 int,
    column3 int,
    column4 int);
insert dbo.new values 
( 1 , 1 , 1 , 1 ),
( 2 , 1 , 2 , 2 ),
( 3 , 3 , 3 , 3 ),
( 4 , 1 , 4 , 4 );

insert dbo.old values 
( 1 , 1 , 1 , 9 ),
( 2 , 1 , 2 , 9 ),
( 3 , 3 , 3 , 9 ),
( 4 , 1 , 4 , 9 );


SELECT TOP(1) WITH TIES 
   dbo.new.[column1], dbo.new.[column2], dbo.new.[column3], dbo.new.[column4] 
FROM dbo.new 
JOIN dbo.old ON dbo.new.[column1]=dbo.old.[column1] 
AND dbo.new.[column2]=dbo.old.[column2] 
AND dbo.new.[column3]=dbo.old.[column3]
where [dbo].[new].[column4] <> [dbo].[old].[column4]
ORDER BY row_number() over(partition by dbo.new.[column2] order by dbo.new.[column1]);

结果是

column1 column2 column3 column4
    1     1      1       1
    3     3      3       3

答案 1 :(得分:1)

您似乎只对第2列感兴趣,所以让我们从选择它开始。 然后在最后添加一个简单的:GROUP BY,你就完成了。

SELECT N.[column2] as myvalue
FROM dbo.new N
JOIN dbo.old O
ON N.[column1]=O.[column1] 
    AND N.[column2]=O.[column2] 
    AND N.[column3]=O.[column3]
WHERE N.[column4] <> O.[column4]
GROUP BY N.[column2]