SQL 查询以从 2 个表中获取公共数据和非公共数据

SQL query to get both common and and non common data from 2 tables

您好,我正在寻找一个查询,它可以在一个查询中同时提供常见数据和非常见数据。

| ID       |  Assay         | req_ind     |
| -------- | -------------- |--------------
| 1.       | 123            | 0           |
| 2.       | 124            | 1           |
| 3.       | 125            | 1           |

Table 2

ID Assay
1 124

结果

required_missing required_present
125 124

基于 table 1 的 req_ind 列,如果 req_ind 为 1 且 table 2 中存在相同的测定,我想将其列为如上。

所需的缺失列可以有多个列。

根据给定的数据,这给出了请求的结果:

WITH table1 as (
   select 1 as ID, 123 as Assay, 0 as req_ind from dual
   union all
   select 2,124,1 from dual
   union all
   select 3,125,1 from dual
   ),
table2 as (
   select 1 as ID, 124 as Assay from dual
),
required_missing as (
   select 
      row_number() over (order by table1.Assay) as R,
      table1.Assay as required_missing
   from table1
   left join table2 on table2.Assay = table1.Assay
   where table1.req_ind=1 and table2.id is null
),
requires_present as (
   select 
      row_number() over (order by table1.Assay) as R,
      table1.Assay as required_present
   from table1
   left join table2 on table2.Assay = table1.Assay
   where table1.req_ind=1 and table2.id is not null
),
results as (
   select row_number() over (order by (id)) as r
   from table1
)
select rm.required_missing, rp.required_present
from results
left join required_missing rm on rm.R = results.R
left join requires_present rp on rp.R = results.R
where rm.R is not null or rp.R is not null;

输出:

REQUIRED_MISSING REQUIRED_PRESENT
125 124

如果你想用逗号分隔列表来表示遗失和现在,那么你可以使用:

SELECT LISTAGG(CASE WHEN t2.assay IS NULL THEN t1.assay END, ',')
         WITHIN GROUP (ORDER BY t1.assay) AS required_missing,
       LISTAGG(t2.assay, ',')
         WITHIN GROUP (ORDER BY t1.assay) AS required_present
FROM   table1 t1
       LEFT OUTER JOIN table2 t2
       ON (t1.assay = t2.assay)
WHERE  t1.req_ind = 1

其中,对于示例数据:

CREATE TABLE table1 (id, assay, req_ind) AS
SELECT 1, 123, 0 FROM DUAL UNION ALL
SELECT 2, 124, 1 FROM DUAL UNION ALL
SELECT 3, 125, 1 FROM DUAL UNION ALL
SELECT 4, 126, 1 FROM DUAL UNION ALL
SELECT 5, 127, 1 FROM DUAL;

CREATE TABLE table2 (id, assay) AS
SELECT 1, 124 FROM DUAL UNION ALL
SELECT 2, 127 FROM DUAL;

输出:

REQUIRED_MISSING REQUIRED_PRESENT
125,126 124,127

如果您想要多行输出,那么:

SELECT required_missing,
       required_present
FROM   (
  SELECT NVL2(t2.assay, 'P', 'M') AS status,
         ROW_NUMBER() OVER (
           PARTITION BY NVL2(t2.assay, 'P', 'M')
           ORDER BY t1.assay
         ) AS rn,
         t1.assay
  FROM   table1 t1
         LEFT OUTER JOIN table2 t2
         ON (t1.assay = t2.assay)
  WHERE  t1.req_ind = 1
)
PIVOT (
  MAX(assay)
  FOR status IN (
    'M' AS required_missing,
    'P' AS required_present
  )
)

输出:

REQUIRED_MISSING REQUIRED_PRESENT
125 124
126 127

db<>fiddle here