La table appropriée, nommée emp
, contient les données suivantes:
CREATE TEMPORARY TABLE emp AS
SELECT * FROM ( VALUES (1,'A'), (2,'B'), (3,'C') );
ID Name
-- ----
1 A
2 B
3 C
Et la sortie ou l'ensemble de résultats de l'opération de manipulation de données doit être comme indiqué ci-dessous:
ID Name
-- ----
1 A
1 A
2 B
2 B
3 C
3 C
La sortie doit être obtenue en respectant les conditions suivantes:
Remarque : Ce scénario m'a été présenté par un intervieweur.
SELECT ta.id, ta.name
FROM emp ta
CROSS JOIN ( VALUES (1), (2) ) tb (id) ;
Une façon serait
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;
Trois façons de plus.
Semblable à la réponse de Paparazzi, en utilisant qu'une jointure NATURAL
devient une jointure CROSS
lorsqu'il n'y a pas de colonne commune:
SELECT e.id, e.name
FROM emp AS e
NATURAL JOIN
(VALUES (1), (2)) AS c (i) ;
Un autre qui utilise UNION DISTINCT
et une colonne supplémentaire pour éviter la suppression des doublons:
SELECT id, name
FROM
( SELECT id, name, 1 AS d
FROM emp
UNION
SELECT id, name, 2
FROM emp
) AS t ;
Abus GROUPING SETS
. Il y a quelque chose d'inattendu et d'ironique dans cette méthode car elle utilise GROUP BY
pour multiplier le nombre de lignes renvoyées:
SELECT id, name
FROM emp
GROUP BY GROUPING SETS ((id, name), (id, name)) ;
Une autre solution qui niquement fonctionne avec les données d'exemple fournies.
select e1.*
from emp e1
join emp e2 on e1.id <> i2.id;
Si l'exigence ou les données d'exemple n'étaient que légèrement différentes, cela ne fonctionnerait pas. Mais l'exigence de doubler le nombre de lignes correspond aux exemples de données qui contiennent exactement deux ID différents pour chaque ID. S'il y avait 4 identifiants différents, cela ne fonctionnerait pas.
La seule chose dont vous avez vraiment besoin est une jointure croisée avec une table à deux lignes. Vous pouvez utiliser celui que vous avez déjà dedans.
select e1.*
from emp e1
cross join (select 1 from emp limit 2) tmp;
http://sqlfiddle.com/#!9/15057/ - utilise une table temporaire implicite, elle pourrait donc également être interdite.
select e1.*
from emp e1
join emp e2 on e2.id IN (1, 2)
order by e1.id;
http://sqlfiddle.com/#!9/15057/6 - vous choisissez simplement deux lignes en utilisant la condition IN () et les utilisez pour générer les doublons.
Si vous utilisez PostgreSQL, mettez un SET RETURN FUNCTION dans la clause ORDER BY
.
CREATE TABLE foo AS
SELECT *
FROM ( VALUES (1,'A'),(2,'B'),(3,'C') ) AS x(id,name);
Et alors
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
Il n'est pas nécessaire que ce soit generate_series
, Vous pouvez également unnest('{1,2}'::int[])
, et vous pouvez également le faire dans la liste de sélection (sauf que vous obtiendrez la série en sortie).