单列合并

时间:2019-01-16 15:19:30

标签: sql sql-server unions

我在不同的数据库中有2个表,我希望能够从names_new中选择所有行,从names中选择丢失的行,并想知道每个行来自何处​​。

+---------------+              +---------------+ 
|     NAMES     |              |   NAMES_NEW   |
+---------------+              +---------------+
| ID |   NAME   |              | ID |   NAME   |
+----+----------+              +----+----------+
|  1 |  Name1   |              |  1 |  Name1!  |
+----+----------+              +----+----------+
|  2 |  Name2   |              |  3 |  Name3   |
+----+----------+              +----+----------+

              +----------------------+ 
              |       RESULTS        |  <-- I want this result
              +----------------------+ 
              | ID |   NAME   | FROM | 
              +----+----------+------+
              |  1 |  Name1!  |  NEW |
              +----+----------+------+
              |  2 |  Name2   |  OLD |
              +----+----------+------+
              |  3 |  Name3   |  NEW |
              +----+----------+------+

像这样的东西,但实际上有效

(
  SELECT
    n.ID as [ID],
    n.NAME as [NAME],
    'OLD' AS [FROM]
  FROM NAMES n
  UNION
  SELECT
    nn.ID as [ID],
    nn.NAME as [NAME],
    'NEW' as [FROM]
  FROM NAMES_NEW nn
)
ORDER BY NAME ASC OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY;

我要在网页上显示此内容。因此,我将需要能够添加分页和不同的where子句。

我在这里创建了一个JDoodle:https://jdoodle.com/a/U9k

2 个答案:

答案 0 :(得分:4)

我认为这里不需要UNION,我认为FULL OUTER JOIN可能会提供更好的解决方案:

SELECT ISNULL(NN.ID,N.ID) AS ID,
       ISNULL(NN.[NAME], N.[NAME]) AS [Name],
       CASE WHEN NN.ID IS NOT NULL THEN 'NEW' ELSE 'OLD' END AS [From]
FROM dbo.NAMES N
     FULL OUTER JOIN dbo.NAMES_NEW NN ON N.ID = NN.ID;

答案 1 :(得分:1)

我会这样使用union all

select nn.id, nn.name, 'new' as which
from names_new nn
union all
select n.id, n.name, 'old' as which
from names_old n
where not exists (select 1 from names_new nn where nn.id = n.id);

这将比较ID。我不确定是否要比较ID或名称(或两者)以进行优先排序。