英文:
JOIN two CTE to create a summary using GROUP BY
问题
SELECT
oba.Structure_type,
SUM(CASE WHEN oba.YEAR_BUILT<='2016' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN EXTRACT(YEAR FROM gika.status_granted_date) >= '2016' THEN 1 ELSE 0 END) AS gik2016,
SUM(CASE WHEN oba.YEAR_BUILT<='2017' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN oba.YEAR_BUILT<='2018' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN oba.YEAR_BUILT<='2019' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN oba.YEAR_BUILT<='2020' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN oba.YEAR_BUILT<='2021' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN oba.YEAR_BUILT<='2022' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN oba.YEAR_BUILT<='2023' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2023
FROM open_bridges oba
LEFT JOIN gikl_all_strucs gika
ON oba.structure_type=gika.structure_type
AND oba.structure_no=gika.structure_no
AND oba.year_built=gika.year_built
AND oba.structure_status_type_code=gika.structure_status_type_code
GROUP BY oba.structure_type
ORDER BY oba.structure_type DESC;
英文:
I have a CTE called open_bridges whose first 24 rows are shown below.
Structure Type | Year Built | Structure Code | Status Granted Date |
---|---|---|---|
BRIDGE | 1958 | F | 12/6/2016 |
TUNNEL | 1961 | L | 3/28/2022 |
BRIDGE | 1999 | F | 1/9/2002 |
RWALL | 1998 | I | 4/17/2000 |
BRIDGE | 2014 | F | 11/7/2018 |
BRIDGE | 2017 | G | 5/08/2020 |
BRIDGE | 2012 | K | 1/9/2017 |
RWALL | 2003 | F | 3/07/2007 |
BRIDGE | 1999 | F | 2/24/2011 |
BRIDGE | 2006 | K | 6/02/2017 |
BRIDGE | 2008 | F | 9/24/2019 |
TUNNEL | 2000 | F | 4/17/2016 |
TUNNEL | 2011 | I | 11/7/2018 |
BRIDGE | 2013 | G | 5/08/2020 |
BRIDGE | 2017 | F | 1/9/2020 |
RWALL | 2003 | F | 3/07/2005 |
TUNNEL | 2011 | I | 11/7/2018 |
BRIDGE | 2013 | G | 5/08/2020 |
BRIDGE | 2017 | F | 1/9/2020 |
RWALL | 2003 | F | 3/07/2005 |
TUNNEL | 2016 | K | 12/5/2019 |
RWALL | 2014 | F | 8/05/2016 |
RWALL | 2015 | F | 1/9/2021 |
BRIDGE | 2017 | K | 3/03/2022 |
I use the following SQL Developer query to get the following result:
SELECT
oba.Structure_type,
SUM(CASE WHEN oba.YEAR_BUILT<='2016' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN oba.YEAR_BUILT<='2017' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN oba.YEAR_BUILT<='2018' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN oba.YEAR_BUILT<='2019' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN oba.YEAR_BUILT<='2020' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN oba.YEAR_BUILT<='2021' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN oba.YEAR_BUILT<='2022' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN oba.YEAR_BUILT<='2023' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2023
FROM open_bridges oba
GROUP BY oba.structure_type,gika.structure_type
ORDER BY oba.structure_type DESC
The result is:
Structure_type | y2016 | y2017 | y2018 | y2019 | y2020 | y2021 | y2022 | y2023 |
---|---|---|---|---|---|---|---|---|
TUNNEL | 3 | 4 | 4 | 4 | 4 | 5 | 5 | 5 |
RWALL | 5 | 5 | 6 | 6 | 6 | 6 | 6 | 6 |
BRIDGE | 6 | 10 | 12 | 13 | 13 | 13 | 13 | 13 |
Then I run another SQL query:
SELECT
gika.Structure_type,
SUM(CASE WHEN EXTRACT(YEAR FROM gika.status_granted_date) >='2016' THEN 1 ELSE 0 END) AS gik2016
FROM gikl_all_strucs gika
GROUP BY gika.structure_type
I get following result:
Structure_type | gik2016 |
---|---|
BRIDGE | 13 |
RWALL | 5 |
TUNNEL | 4 |
However, its combining both results that gives wrong values.
The SQL query I tried is as follows:
SELECT
oba.STructure_type,
SUM(CASE WHEN oba.YEAR_BUILT<='2016' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN EXTRACT(YEAR FROM gika.current_status_granted_date) >='2016' THEN 1 ELSE 0 END) AS gik2016,
SUM(CASE WHEN oba.YEAR_BUILT<='2017' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN oba.YEAR_BUILT<='2018' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN oba.YEAR_BUILT<='2019' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN oba.YEAR_BUILT<='2020' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN oba.YEAR_BUILT<='2021' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN oba.YEAR_BUILT<='2022' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN oba.YEAR_BUILT<='2023' OR oba.YEAR_BUILT IS NULL THEN 1 ELSE 0 END) AS y2023
FROM open_bridges oba LEFT JOIN gikl_all_strucs gika
ON oba.structure_type=gika.structure_type
AND oba.structure_no=gika.structure_no
AND oba.year_built=gika.year_built
AND oba.structure_status_type_code=gika.structure_status_type_code
GROUP BY oba.structure_type
ORDER BY oba.structure_type DESC
and the result I get is:
Structure_type | y2016 | gik2016 | y2017 | y2018 | y2019 | y2020 | y2021 | y2022 | y2023 |
---|---|---|---|---|---|---|---|---|---|
TUNNEL | 3 | 0 | 4 | 4 | 4 | 4 | 5 | 5 | 5 |
RWALL | 5 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
BRIDGE | 6 | 0 | 12 | 12 | 13 | 13 | 13 | 13 | 13 |
I get '0' in gik2016 column.
Can anyone please assist me in rectifying my SQL query so I can get the following result:
Structure_type | y2016 | gik2016 | y2017 | y2018 | y2019 | y2020 | y2021 | y2022 | y2023 |
---|---|---|---|---|---|---|---|---|---|
TUNNEL | 3 | 13 | 4 | 4 | 4 | 4 | 5 | 5 | 5 |
RWALL | 5 | 5 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
BRIDGE | 6 | 4 | 12 | 12 | 13 | 13 | 13 | 13 | 13 |
*Please note that open_bridge and gikl_all_strucs are two CTEs derived from the same table. The only difference is a WHERE caluse. open_bridge deals with structure type IN ('F') whereas gikl_all_strucs is structure type IN ('G','I','K','L').
I shall be obliged if some one can help me write a SQL query to get the result I want.
My apologies if I am not able to explain my question properly. If you require more information please let me know.
答案1
得分: 1
将两个表联合在一起,然后进行数据透视:
SELECT Structure_type,
SUM(CASE WHEN type = 'GAS' AND year_built >= 2016 THEN 1 ELSE 0 END) AS gik2016
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2016 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2017 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2018 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2019 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2020 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2021 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2022 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT <= 2023 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2023
FROM (
SELECT structure_type,
year_built,
'OB' AS type
FROM open_bridges
UNION ALL
SELECT structure_type,
EXTRACT(YEAR FROM status_granted_date),
'GAS'
FROM gikl_all_strucs
WHERE status_granted_date >= DATE '2016-01-01'
)
GROUP BY
structure_type
或者,如果open_bridges
和gikl_all_strucs
都是基于相同表的视图,那么可以直接使用基本表:
SELECT Structure_type,
SUM(CASE WHEN structure_type IN ('G','I','K','L') AND year_built >= 2016 THEN 1 ELSE 0 END) AS gik2016
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2016 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2017 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2018 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2019 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2020 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2021 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2022 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT <= 2023 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2023
FROM your_base_table
GROUP BY
structure_type
英文:
UNION
both tables together and then pivot:
SELECT Structure_type,
SUM(CASE WHEN type = 'GAS' AND year_built >=2016 THEN 1 ELSE 0 END) AS gik2016
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2016 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2017 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2018 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2019 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2020 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2021 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2022 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN type = 'OB' AND (YEAR_BUILT<=2023 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2023
FROM (
SELECT structure_type,
year_built,
'OB' AS type
FROM open_bridges
UNION ALL
SELECT structure_type,
EXTRACT(YEAR FROM status_granted_date),
'GAS'
FROM gikl_all_strucs
WHERE status_granted_date >= DATE '2016-01-01'
)
GROUP BY
structure_type
Or, if both open_bridges
and gikl_all_strucs
are views based on the same table then just use the base table:
SELECT Structure_type,
SUM(CASE WHEN structure_type IN ('G','I','K','L') AND year_built >=2016 THEN 1 ELSE 0 END) AS gik2016
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2016 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2016,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2017 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2017,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2018 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2018,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2019 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2019,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2020 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2020,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2021 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2021,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2022 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2022,
SUM(CASE WHEN structure_type = 'F' AND (YEAR_BUILT<=2023 OR YEAR_BUILT IS NULL) THEN 1 ELSE 0 END) AS y2023
FROM your_base_table
GROUP BY
structure_type
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论