How to force returning multiple lines in SQL when there are duplicates inside "in" clause (Oracle)
Solution 1:
In Oracle, you can INNER JOIN
to a table collection expression:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub
ON upub.usr_id = pack.usr_id_publication
INNER JOIN TABLE(SYS.ODCIVARCHAR2LIST(
'07655_23687_30863',
'07655_23687_30863',
'07432_76544_67890'
)) l
ON pack.pack_lib = l.COLUMN_VALUE
ORDER BY pack.date_publication DESC;
Which, for the sample data:
CREATE TABLE t_user(usr_id, usr_nni, usr_email) AS
SELECT 1, 1, '[email protected]' FROM DUAL UNION ALL
SELECT 2, 2, '[email protected]' FROM DUAL;
CREATE TABLE t_package(usr_id_publication, pack_lib, date_publication) AS
SELECT 1, '07655_23687_30863', DATE '2022-01-01' FROM DUAL UNION ALL
SELECT 2, '07432_76544_67890', DATE '2022-01-02' FROM DUAL;
Outputs:
PACK_LIB USR_NNI USR_EMAIL 07432_76544_67890 2 [email protected] 07655_23687_30863 1 [email protected] 07655_23687_30863 1 [email protected]
If you do not have visibility of the SYS.ODCI*LIST
types then you may be able to create a user-defined collection type:
CREATE TYPE string_list AS TABLE OF VARCHAR2(20);
then use:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub
ON upub.usr_id = pack.usr_id_publication
INNER JOIN TABLE(string_list(
'07655_23687_30863',
'07655_23687_30863',
'07432_76544_67890'
)) l
ON pack.pack_lib = l.COLUMN_VALUE
ORDER BY pack.date_publication DESC;
db<>fiddle here
Solution 2:
You need to use JOIN
instead of semi-join (the IN
syntax). The following query should work on Oracle:
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub ON upub.usr_id = pack.usr_id_publication
LEFT OUTER JOIN (
SELECT '07655_23687_30863' pack_lib FROM dual
UNION ALL
SELECT '07655_23687_30863' FROM dual
) t
ON pack.pack_lib = t.pack_lib;
SQL Server and PostgreSQL should allow also the following syntax
SELECT pack.pack_lib,
upub.usr_nni,
upub.usr_email
FROM t_package pack
LEFT OUTER JOIN t_user upub ON upub.usr_id = pack.usr_id_publication
LEFT OUTER JOIN (VALUES ('07655_23687_30863'), ('07655_23687_30863')) AS t(pack_lib)
ON pack.pack_lib = t.pack_lib;