首页 > 解决方案 > 如何编写涉及多个选择的 Oracle SQL 查询

问题描述

我有这个查询,它给出了项目的名称、平均价格和特定年份的计数,如下所示。

name      Avg_price_2019    count
---------------------------------
X         23.9              234
Y         21.8               59

SQL:

SELECT 
    AVG(Amount) Avg_price_2019, name 
FROM
    (SELECT 
         name, SUM(price_amount) Amount, COUNT(*) 
     FROM 
         myTable
     WHERE
         (To_date("Activity Date", 'mm-dd-yyyy') >= TO_DATE('09/01/2019', 'mm/dd/yyyy'))
         AND (To_date("Activity Date", 'mm-dd-yyyy') <= TO_DATE('09/17/2019','mm/dd/yyyy')) 
     GROUP BY
         name)
GROUP BY
    name;

我希望它返回更多年,如下所示

name | Avg price 2018 | count | Avg price 2019 | count

对于 2018 年的结果,我需要相同的查询,只是更改年份。

如何在同一个查询中组合这两个选择以产生上述结果?

标签: sqloraclepivotaggregate-functions

解决方案


您似乎想要条件聚合。您的查询很可能简化如下:

SELECT
    name 
    AVG(CASE WHEN EXTRACT(YEAR FROM Activity_Date) = 2019 THEN Amount END) avg_price_2019,
    SUM(CASE WHEN EXTRACT(YEAR FROM Activity_Date) = 2019 THEN 1 ELSE 0 END) count_2019,  
    AVG(CASE WHEN EXTRACT(YEAR FROM Activity_Date) = 2018 THEN Amount END) avg_price_2018,
    SUM(CASE WHEN EXTRACT(YEAR FROM Activity_Date) = 2018 THEN 1 ELSE 0 END) count_2018
FROM myTable 
GROUP BY name

您似乎将日期存储为字符串,格式为mm-dd-yyyy。您可以使用SUBSTR()提取年份部分,如:

SELECT
    name 
    AVG(CASE WHEN SUBSTR(Activity_Date, -4) = '2019' THEN Amount END) avg_price_2019,
    SUM(CASE WHEN SUBSTR(Activity_Date, -4) = '2019' THEN 1 ELSE 0 END) count_2019,  
    AVG(CASE WHEN SUBSTR(Activity_Date, -4) = '2018' THEN Amount END) avg_price_2018,
    SUM(CASE WHEN SUBSTR(Activity_Date, -4) = '2018' THEN 1 ELSE 0 END) count_2018
FROM myTable 
GROUP BY name

最后,如果要过滤一年中的特定时间段(9 月 1 日至 9 月 17 日),则可以WHERE在查询中添加子句。仍然假设日期存储为字符串,这可能是:

WHERE SUBSTR(Activity_Date, 1, 5) BETWEEN '09-01' AND '09-17'

推荐阅读