采访中给了我这个问题。有2个表A&B(它们只有一列id),其中包含以下数据
Table A
id
--
1
2
3
Table B
id
--
2
3
4
Run Code Online (Sandbox Code Playgroud)
我需要产生以下类型的输出:
id | Present
------------
1 | "In A"
2 | "In A & In B"
3 | "In A & In B"
4 | "In B"
Run Code Online (Sandbox Code Playgroud)
我提供了一个解决方案using Union子句,如下所示:
SELECT id, "In A" FROM A WHERE id NOT IN (SELECT id FROM B)
UNION
SELECT id, "In A & In B" WHERE id IN (SELECT id FROM B)
UNION
SELET id, "In B" WHERE id NOT IN (SELECT id FROM A)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我使用3个单独的查询并将UNION其组合在一起。我认为Interview只是在寻找我的方法,而不是确切的查询。就是说,在我提出解决方案之后,他告诉我至少有一种解决方案仅使用2个查询,并且还存在一种仅使用1个查询的解决方案。我尝试使用FULL OUTER JOIN,但无法提出任何具体建议。
那么,获得以下输出的更好的查询是什么?采访者没有提到任何特定的数据库,所以我认为存在一个通用的解决方案。但是,如果查询特定于某种SQL风格就可以了。泛型虽然会很好。
这是一个与DBMS完全无关的答案(尽管由于缺乏对的支持而无法在MySQL上运行FULL OUTER JOIN):
SELECT COALESCE(A.id, B.id) AS id,
CASE WHEN A.id IS NULL THEN 'In B'
WHEN B.id IS NULL THEN 'In A'
ELSE 'In A & In B' END AS Present
FROM A
FULL OUTER JOIN B ON B.id = A.id
Run Code Online (Sandbox Code Playgroud)
输出:
id present
1 In A
2 In A & In B
3 In A & In B
4 In B
Run Code Online (Sandbox Code Playgroud)
该查询依赖于以下事实:如果外部联接的第二个表中没有匹配的行,则将JOIN编辑具有NULL值的行。因此,如果A.id IS NULL,则意味着该值仅在表B中。如果B.id IS NULL,则该值仅在表A中。并且,如果两个id值都为非NULL,则该值必须在两个表中。
Oracle演示
SQL Server演示
PostgreSQL演示