3

假设我在一个 UNION 中组合了三个子查询。

select * from (
    select nr, pos, '1' from foo
    union all
    select nr, pos, '2' from bar
    union all
    select nr, pos, '3' from foobar
)

我需要的是一个结果,它foobarnr在第一个子查询(from foo)没有返回值的情况下才返回行。

nr列必须是唯一的条件,而不是整行,因此 UNION 无济于事。我对吗?

抱歉,我不知道如何更好地解释这一点。

4

4 回答 4

2

在最后一个子句添加一个where子句,select使其仅在前两个查询没有结果时才返回结果。请参阅下面的更新查询:

select nr, pos, '1' from foo
union all
select nr, pos, '2' from bar
union all
select nr, pos, '3' from foobar fb
 where not exists (select 1 from foo f where fb.nr = f.nr)
   and not exists (select 1 from bar b where fb.nr = b.nr)
于 2012-12-02T15:20:25.260 回答
1

也许是这样的把戏:

select distinct min(x), nr, pos from (
    select nr, pos, '1' as x from foo
    union all
    select nr, pos, '2' from bar
    union all
    select nr, pos, '3' from foobar
)
group by nr, pos
于 2012-12-02T16:07:36.763 回答
0

你似乎需要:

SELECT *
  FROM (SELECT nr, pos, '1' AS code FROM foo
        UNION ALL
        SELECT nr, pos, '2' AS code FROM bar
        UNION ALL
        SELECT nr, pos, '3' AS code
          FROM foobar
         WHERE nr NOT IN (SELECT nr FROM foo)
       )

您可以扩展该处理,以便bar不选择 from 中的项目,除非它们未在 中列出foo,并且不选择 in 中的项目,foobar除非它们未在foo或中列出bar。显然,您可以选择code(也许source)以外的名称作为数值的列名,但您应该为其提供一个名称。

于 2012-12-02T16:05:14.870 回答
0

如果您使用的 SQL 产品支持排名函数,您可以尝试以下操作:

SELECT nr, pos, src
FROM (
  SELECT *, RANK() OVER (PARTITION BY nr ORDER BY src) AS rnk
  FROM (
    SELECT nr, pos, '1' AS src FROM foo
    UNION ALL
    SELECT nr, pos, '3' AS src FROM foobar
  ) s
) s
WHERE rnk = 1
UNION ALL
SELECT nr, pos, '2' AS src FROM bar
;

最里面的子查询联合来自foo和的行foobar。中间层子查询nr根据提供它们的源表对值进行排名:

  • 对 from 的行foobar进行排名,就好像在;中找不到1相应的值一样nrfoo

  • 否则,它的foo行将被列为1.

排名结果集被过滤rnk = 1,然后与bar表联合(据我所知,它是无条件返回的)。

于 2012-12-02T22:58:31.020 回答