在 SQL 中使用 "OR" 和 "INTERSECT"
Use of "OR" and "INTERSECT" in SQL
我只有一个Table Table一个像下面这样:
ID
Type
Date
First
BS
12-APR-22
First
GH
10-MAY-22
First
MPN
15-APR-22
Second
BS
10-MAY-22
Second
MPN
10-MAY-22
Third
GH
10-MAY-22
Third
BS
10-MAY-22
Fourth
MPN
15-MAY-22
Fourth
GH
15-MAY-22
Fifth
GH
06-MAY-22
我想实现如下输出:
ID
Type
Date
First
BS
12-APR-22
First
GH
10-MAY-22
First
MPN
15-APR-22
Second
BS
10-MAY-22
Second
MPN
10-MAY-22
Third
GH
10-MAY-22
Third
BS
10-MAY-22
我有如下查询,但没有看到任何输出:
Select ID from TableA
WHERE
(DATE BETWEEN '13-APR-22' AND '11-MAY-22')
AND
(
(TYPE = 'BS' AND TYPE = 'GH')
OR
(TYPE = 'GH' AND TYPE = 'MPN')
OR
(TYPE = 'BS' AND TYPE = 'MPN')
);
我也尝试了以下方法,但在输出中出现错误:
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'BS')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'GH')
OR
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'GH')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'MPN')
OR
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'BS')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'MPN')
请帮助我实现我正在寻找的输出。提前致谢!
我会在这里使用聚合方法:
WITH cte AS (
SELECT ID
FROM TableA
WHERE "DATE" BETWEEN date '2022-04-13' AND date '2022-05-11'
GROUP BY ID
HAVING
(COUNT(CASE WHEN TYPE = 'BS' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'GH' THEN 1 END) > 0)
OR
(COUNT(CASE WHEN TYPE = 'GH' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'MPN' THEN 1 END) > 0)
OR
(COUNT(CASE WHEN TYPE = 'BS' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'MPN' THEN 1 END) > 0)
)
SELECT *
FROM TableA
WHERE ID IN (SELECT ID FROM cte);
使用分析函数和条件聚合,这样您就不必查询 table 两次:
SELECT id, type, "DATE"
FROM (
SELECT t.*,
COUNT(
CASE
WHEN TYPE = 'BS'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_bs,
COUNT(
CASE
WHEN TYPE = 'GH'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_gh,
COUNT(
CASE
WHEN TYPE = 'MPN'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_mpn
FROM tableA t
)
WHERE (num_bs > 0 AND num_gh > 0)
OR (num_bs > 0 AND num_mpn > 0)
OR (num_gh > 0 AND num_mpn > 0)
其中,对于示例数据:
CREATE TABLE tablea (ID, Type, "DATE") AS
SELECT 'First', 'BS', DATE '2022-04-12' FROM DUAL UNION ALL
SELECT 'First', 'GH', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'First', 'MPN', DATE '2022-04-15' FROM DUAL UNION ALL
SELECT 'Second', 'BS', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Second', 'MPN', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Third', 'GH', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Third', 'BS', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Fourth', 'MPN', DATE '2022-05-15' FROM DUAL UNION ALL
SELECT 'Fourth', 'GH', DATE '2022-05-15' FROM DUAL UNION ALL
SELECT 'Fifth', 'GH', DATE '2022-05-06' FROM DUAL;
输出:
ID
TYPE
DATE
First
GH
10-MAY-22
First
MPN
15-APR-22
First
BS
12-APR-22
Second
BS
10-MAY-22
Second
MPN
10-MAY-22
Third
GH
10-MAY-22
Third
BS
10-MAY-22
db<>fiddle here
我只有一个Table Table一个像下面这样:
ID | Type | Date |
---|---|---|
First | BS | 12-APR-22 |
First | GH | 10-MAY-22 |
First | MPN | 15-APR-22 |
Second | BS | 10-MAY-22 |
Second | MPN | 10-MAY-22 |
Third | GH | 10-MAY-22 |
Third | BS | 10-MAY-22 |
Fourth | MPN | 15-MAY-22 |
Fourth | GH | 15-MAY-22 |
Fifth | GH | 06-MAY-22 |
我想实现如下输出:
ID | Type | Date |
---|---|---|
First | BS | 12-APR-22 |
First | GH | 10-MAY-22 |
First | MPN | 15-APR-22 |
Second | BS | 10-MAY-22 |
Second | MPN | 10-MAY-22 |
Third | GH | 10-MAY-22 |
Third | BS | 10-MAY-22 |
我有如下查询,但没有看到任何输出:
Select ID from TableA
WHERE
(DATE BETWEEN '13-APR-22' AND '11-MAY-22')
AND
(
(TYPE = 'BS' AND TYPE = 'GH')
OR
(TYPE = 'GH' AND TYPE = 'MPN')
OR
(TYPE = 'BS' AND TYPE = 'MPN')
);
我也尝试了以下方法,但在输出中出现错误:
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'BS')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'GH')
OR
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'GH')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'MPN')
OR
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'BS')
INTERSECT
Select ID from TableA WHERE (DATE BETWEEN '13-APR-22' AND '11-MAY-22') AND (TYPE = 'MPN')
请帮助我实现我正在寻找的输出。提前致谢!
我会在这里使用聚合方法:
WITH cte AS (
SELECT ID
FROM TableA
WHERE "DATE" BETWEEN date '2022-04-13' AND date '2022-05-11'
GROUP BY ID
HAVING
(COUNT(CASE WHEN TYPE = 'BS' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'GH' THEN 1 END) > 0)
OR
(COUNT(CASE WHEN TYPE = 'GH' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'MPN' THEN 1 END) > 0)
OR
(COUNT(CASE WHEN TYPE = 'BS' THEN 1 END) > 0 AND
COUNT(CASE WHEN TYPE = 'MPN' THEN 1 END) > 0)
)
SELECT *
FROM TableA
WHERE ID IN (SELECT ID FROM cte);
使用分析函数和条件聚合,这样您就不必查询 table 两次:
SELECT id, type, "DATE"
FROM (
SELECT t.*,
COUNT(
CASE
WHEN TYPE = 'BS'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_bs,
COUNT(
CASE
WHEN TYPE = 'GH'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_gh,
COUNT(
CASE
WHEN TYPE = 'MPN'
AND "DATE" >= DATE '2022-04-13'
AND "DATE" < DATE '2022-05-12'
THEN 1
END
) OVER (PARTITION BY id) AS num_mpn
FROM tableA t
)
WHERE (num_bs > 0 AND num_gh > 0)
OR (num_bs > 0 AND num_mpn > 0)
OR (num_gh > 0 AND num_mpn > 0)
其中,对于示例数据:
CREATE TABLE tablea (ID, Type, "DATE") AS
SELECT 'First', 'BS', DATE '2022-04-12' FROM DUAL UNION ALL
SELECT 'First', 'GH', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'First', 'MPN', DATE '2022-04-15' FROM DUAL UNION ALL
SELECT 'Second', 'BS', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Second', 'MPN', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Third', 'GH', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Third', 'BS', DATE '2022-05-10' FROM DUAL UNION ALL
SELECT 'Fourth', 'MPN', DATE '2022-05-15' FROM DUAL UNION ALL
SELECT 'Fourth', 'GH', DATE '2022-05-15' FROM DUAL UNION ALL
SELECT 'Fifth', 'GH', DATE '2022-05-06' FROM DUAL;
输出:
ID TYPE DATE First GH 10-MAY-22 First MPN 15-APR-22 First BS 12-APR-22 Second BS 10-MAY-22 Second MPN 10-MAY-22 Third GH 10-MAY-22 Third BS 10-MAY-22
db<>fiddle here