数据比较问题

时间:2012-04-26 02:16:57

标签: sql sql-server sql-server-2008 stored-procedures sql-server-2008-r2

我有以下的SQL查询:

select @table1 as DataState, *  from
(select * from importedcsvclients 
except 
select * from tblClients) x
union all
select @table2 as DataState, *  from
(select * from tblClients 
except select *  
from importedcsvclients) x

上面的代码工作正常,但是,如果table1和table2包含相似的数据,则两个记录都会显示。

任何人都可以帮助我使查询工作:

获取table1和table2的结果,但只有在table1中不存在相同名称时才显示table2数据。

感谢。

对于信息:

table1
ID   Name
1    TestA
2    TestB    
3    TestC
4    TestD

table2
ID   Name
1    TestE
2    TestF    
3    TestG
4    TestD

Results:
Name     DataState
TestA    table1
TestB    table1
TestC    table1
TestD    table1
TestE    table2
TestF    table2
TestG    table2

3 个答案:

答案 0 :(得分:3)

使用EXCEPT非常诱人,但正如您所发现的那样,从具有一点复杂性的任何东西中获取正确的结果并不总是那么简单。这是尝试使用CTE后的结果:

DECLARE @table1 TABLE(ID INT, Name VARCHAR(32));    
INSERT @table1 VALUES (1,'TestA'), (2,'TestB'), (3,'TestC'), (4,'TestD');

DECLARE @table2 TABLE(ID INT, Name VARCHAR(32));
INSERT @table2 VALUES (1,'TestE'), (2,'TestF'), (3,'TestG'), (4,'TestD');

;WITH x AS 
(
  SELECT m, Name, rn = ROW_NUMBER() OVER (PARTITION BY Name ORDER BY m)
  FROM 
  (
    SELECT m = 'table1', Name FROM @table1
    UNION ALL 
    SELECT m = 'table2', Name FROM @table2
  ) AS y
)
SELECT Name, DataState = m
  FROM x 
  WHERE rn = 1
  ORDER BY Name;

结果:

Name        DataState
---------   ---------
TestA       table1
TestB       table1
TestC       table1
TestD       table1
TestE       table2
TestF       table2
TestG       table2

答案 1 :(得分:0)

在(pesudo)关系代数中:

table1 UNION ( table2 NOT MATCH table1 )

在TSQL中(添加DataState):

SELECT ID, Name, 
       'table1' AS DataState
  FROM table1
UNION
SELECT ID, Name,
       'table2' AS DataState
  FROM table2
 WHERE Name NOT IN ( SELECT Name FROM table1 );

包括您的样本数据测试数据:

WITH table1 
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 'TestA'),
                     (2, 'TestB'),    
                     (3, 'TestC'),
                     (4, 'TestD')
             ) AS T (ID, Name)
     ),
     table2
     AS
     (
      SELECT * 
        FROM (
              VALUES (1, 'TestE'),
                     (2, 'TestF'),    
                     (3, 'TestG'),
                     (4, 'TestD')
             ) AS T (ID, Name)
     )
SELECT ID, Name, 
       'table1' AS DataState
  FROM table1
UNION
SELECT ID, Name,
       'table2' AS DataState
  FROM table2
 WHERE Name NOT IN ( SELECT Name FROM table1 );

答案 2 :(得分:0)

我现在用下面的。 感谢您的帮助。

DECLARE @sql VARCHAR(8000)
SET @sql = 'SELECT ''' + @table1 + ''' AS DataState, * FROM
(SELECT ' + @columnlist + ' FROM ' + @table1 + '
    EXCEPT
SELECT ' + @columnlist + ' FROM ' + @table2 + ') x
    UNION
SELECT ''' + @table2 + ''' AS DataState, * from
    (SELECT ' + @columnlist + ' FROM ' + @table2 + '
        INTERSECT
    SELECT ' + @columnlist + ' FROM ' + @table1 +') x'

EXEC(@sql)