如何在不使用 UNION ALL 或临时表的情况下显示每个存储的行两次?

Anu*_*nup 8 interview-question duplication

名为 的相关表emp包含以下数据:

CREATE TEMPORARY TABLE emp AS
SELECT * FROM ( VALUES (1,'A'), (2,'B'), (3,'C') );

 ID  Name
 --  ----
 1    A
 2    B
 3    C
Run Code Online (Sandbox Code Playgroud)

数据操作操作的输出或结果集应如下所示:

 ID  Name 
 --  ----
 1    A
 1    A 
 2    B
 2    B
 3    C
 3    C
Run Code Online (Sandbox Code Playgroud)

要求

必须获得符合以下条件的输出:

  • 未使用 UNION ALL 运算符与所采用的 SELECT 语句相关联
  • 不使用临时表
  • 不对现有表使用 UPDATE 操作

注意:这个场景是一个面试官给我带来的。

pap*_*zzo 18

SELECT ta.id, ta.name
FROM emp ta 
CROSS JOIN ( VALUES (1), (2) ) tb (id) ;
Run Code Online (Sandbox Code Playgroud)


Mar*_*ith 11

一种方法是

SELECT COALESCE(a.id, b.id) AS id,
       COALESCE(a.name, b.name) AS name
FROM emp a 
     FULL OUTER JOIN emp b ON 1=0
ORDER BY id;
Run Code Online (Sandbox Code Playgroud)


ype*_*eᵀᴹ 10

还有三种方式。

类似于狗仔队的回答,当没有公共列时,利用NATURAL连接变成CROSS连接:

SELECT e.id, e.name
FROM emp AS e 
  NATURAL JOIN
    (VALUES (1), (2)) AS c (i) ;
Run Code Online (Sandbox Code Playgroud)

另一个使用UNION DISTINCT和一个额外的列来避免删除重复项:

SELECT id, name
FROM 
    ( SELECT id, name, 1 AS d
      FROM emp
      UNION 
      SELECT id, name, 2
      FROM emp
    ) AS t ; 
Run Code Online (Sandbox Code Playgroud)

滥用GROUPING SETS。这个方法有一些出乎意料和讽刺的地方,因为它GROUP BY用来乘以返回的行数:

SELECT id, name
FROM emp 
GROUP BY GROUPING SETS ((id, name), (id, name)) ;
Run Code Online (Sandbox Code Playgroud)

  • 我将问题读为“不允许使用 UNION ALL” (4认同)

a_h*_*ame 5

另一种适用于给定示例数据的解决方案。

select e1.*
from emp e1
  join emp e2 on e1.id <> i2.id;
Run Code Online (Sandbox Code Playgroud)

如果要求或示例数据只有一点不同,这将不起作用。但是将行数加倍的要求适合包含正好包含每个 ID 不同的两个 ID 的示例数据。如果有 4 个不同的 ID,这将不会起作用。