emp
という名前の関連テーブルには、次のデータが含まれています。
CREATE TEMPORARY TABLE emp AS
SELECT * FROM ( VALUES (1,'A'), (2,'B'), (3,'C') );
ID Name
-- ----
1 A
2 B
3 C
また、データ操作操作の出力または結果セットは、次のようになります。
ID Name
-- ----
1 A
1 A
2 B
2 B
3 C
3 C
次の条件に従って出力を取得する必要があります。
注:このシナリオはインタビュアーによって持ち込まれました。
SELECT ta.id, ta.name
FROM emp ta
CROSS JOIN ( VALUES (1), (2) ) tb (id) ;
一つの方法は
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;
さらに3つの方法。
パパラッチの回答と同様に、NATURAL
結合がCROSS
結合になることを利用して、共通の列がない場合:
SELECT e.id, e.name
FROM emp AS e
NATURAL JOIN
(VALUES (1), (2)) AS c (i) ;
もう1つはUNION DISTINCT
と追加の列を使用して重複の削除を回避します。
SELECT id, name
FROM
( SELECT id, name, 1 AS d
FROM emp
UNION
SELECT id, name, 2
FROM emp
) AS t ;
不正使用GROUPING SETS
。返される行数を乗算するためにGROUP BY
を使用するため、このメソッドには予想外の皮肉な点があります。
SELECT id, name
FROM emp
GROUP BY GROUPING SETS ((id, name), (id, name)) ;
onlyという別のソリューションは、指定されたサンプルデータで機能します。
select e1.*
from emp e1
join emp e2 on e1.id <> i2.id;
要件またはサンプルデータが少しだけ異なる場合、これは機能しません。ただし、行数を2倍にする必要性は、IDごとに異なる2つのIDを正確に含むサンプルデータに適合します。 4つの異なるIDがある場合、これは動作しません。
本当に必要なのは、2行のテーブルへのクロス結合だけです。そこにあるものを使うことができます。
select e1.*
from emp e1
cross join (select 1 from emp limit 2) tmp;
http://sqlfiddle.com/#!9/15057/ -暗黙の一時テーブルを使用するため、禁止される場合もあります。
select e1.*
from emp e1
join emp e2 on e2.id IN (1, 2)
order by e1.id;
http://sqlfiddle.com/#!9/15057/6 -IN()条件を使用して2つの行を選択し、それらを使用して重複を生成します。
PostgreSQLを使用している場合は、_ORDER BY
_句に SET RETURN FUNCTION を挿入します。
_CREATE TABLE foo AS
SELECT *
FROM ( VALUES (1,'A'),(2,'B'),(3,'C') ) AS x(id,name);
_
その後
_SELECT id,name
FROM foo
ORDER BY 1, generate_series(1,2);
id | name
----+------
1 | A
1 | A
2 | B
2 | B
3 | C
3 | C
_
_generate_series
_である必要はありません。unnest('{1,2}'::int[])
を使用することもできます。また、選択リストを使用することもできます(出力にシリーズが表示される場合を除きます)。