从两个不同的表中获取空值?

时间:2011-03-17 19:03:04

标签: sql sql-server-2008 union

我有一张像这样的大桌子(主要)

person_id    fee        ref_id    <otherfields>
1           foo        23
1            bar        null
1            abc        23
2            xyz        34

ref_id的许多值都是null,我需要检索它们。顺便说一句,我需要选择,而不是更新。 我有两个其他表d1,d2包含必要的缺少ref_id(以及不同的字段),可以使用person_id引用它们。 person_id可能不存在于其中一个表中(例如,它可能不在d1中,但它在d2中)

我可以使用其中一个表填写一些ref_id,但是我如何使用另一个表来检索剩余空值的值?联盟听起来对我好吗?但是我正在努力争取它,因为它给了我比我原来更多的行,这是不对的。

SQL Server 2008

编辑:d1,d2具有相同的(person_id,ref_id)元组

3 个答案:

答案 0 :(得分:4)

您想要加入,并且您可能希望使用COALESCE,例如:

SELECT person_id, fee,
   COALESCE (m.ref_id, d1.ref_id, d2.ref_id) as 'ref_id',
   ...
FROM table t
LEFT JOIN d1
  ON d1.person_id = t.person_id
LEFT JOIN d2
  ON d2.person_id = t.person_id
WHERE ...

这将从这3个表中为您提供ref_id的第一个非NULL值。

修改

为了澄清您的想法,UNION垂直连接数据集或表格,如

SELECT 1,2,3
UNION
SELECT 4,5,6

会给你

1,2,3
4,5,6

JOIN按行连接表,将一个表中的一行链接到另一个表中的一行,以使用两个表中的值“扩展”该行。

答案 1 :(得分:1)

我认为JNK的答案是最好的。但只是为了展示另一种方法,您可以将其作为UNION的单个连接来实现。根据数据集,一种方法或另一种方法可能更有效。

SELECT person_id, fee,
   COALESCE (m.ref_id, d.ref_id) as 'ref_id',
   ...
FROM table t
LEFT JOIN (SELECT person_id, ref_id FROM d1 UNION ALL SELECT person_id, ref_id FROM d2) d
  ON d.person_id = t.person_id

如果d1和d2具有相同person_id的行,则返回的行数将多于原始表中的行数。如果它们具有相同的(person_id,ref_id)元组,那么将UNION ALL更改为简单的UNION应解决该问题;否则,您需要在问题中更具体,因为您可以从d1或d2获得不同的结果。

答案 2 :(得分:0)

如下所示。请注意,如果d1或d2中的任何一行具有同一person_id的多行,则仍可能获得比主表更多的行。如果没有,它不应该给你更多的行。

Select
      m.*
    , d1.*
    , d2.*
From
    main m
Left Join
    d1
On
    m.person_id = d1.person_id
    And
    m.ref_id Is Null
Left Join
    d2
On
    m.person_id = d1.person_id
    And
    m.ref_id Is Null
    And
    d1.ref_id Is Null