sql - Oracle SQL : Simplifying my seemingly-horrendous subquery collection

标签 sql oracle simplify

我有一个相当大的查询用于获取一堆结果,而且我几乎可以肯定这不是这样做的方法。很脏。这是可恶的。首先,让我解释一下我想要的表结构:

+------------------+------+------+------+------+--------+
|   CURRENT_DATE   |  RO  |  FL  |  LM  |  AO  |  TOTAL |
+------------------+------+------+------+------+--------+
|    1/2/2012      |  31  |  33  |  70  |  10  |   144  |
+------------------+------+------+------+------+--------+

以上数据集收集自下表:

+---------------+--------------------+
|  CURRENT_DATE |  PORTABLE_PEANUTS  |
+---------------+--------------------+
|   1/2/2012    |         RO         |
+---------------+--------------------+
|   2/4/2013    |         FL         |
+---------------+--------------------+
|   3/6/2014    |         LM         |
+---------------+--------------------+
|   4/8/2015    |         AO         |
+---------------+--------------------+

本质上,我试图收集在特定日期 PORTABLE_PEANUTS 发生的所有情况、发生的频率以及具体发生的情况。

这是我正在使用的查询:

SELECT total.CURRENT_DATE, results.RO, results.FL, results.LM, results.AO, total.TOTAL FROM 
(
    SELECT CURRENT_DATE, SUM(RO+FL+LM+AO) TOTAL FROM 
    (
        SELECT a.CURRENT_DATE, a.RO, b.FL, c.LM, d.AO FROM 
        (
            SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) RO FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'RO'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')
    ) a
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) FL FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'FL'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) b ON a.CURRENT_DATE = b.CURRENT_DATE
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) LM FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'LM'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) c ON a.CURRENT_DATE = c.CURRENT_DATE
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) AO FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'AO'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) d ON a.CURRENT_DATE = d.CURRENT_DATE
) 
GROUP BY CURRENT_DATE
) total
JOIN
(
    SELECT a.CURRENT_DATE, a.RO, b.FL, c.LM, d.AO FROM 
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) RO FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'RO'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')
    ) a
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) FL FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'FL'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) b ON a.CURRENT_DATE = b.CURRENT_DATE
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) LM FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'LM'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) c ON a.CURRENT_DATE = c.CURRENT_DATE
    JOIN
    (
        SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') CURRENT_DATE, COUNT(PORTABLE_PEANUTS) AO FROM CORE.DATE_TEST
            WHERE PORTABLE_PEANUTS LIKE 'AO'
        GROUP BY  TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')    
    ) d ON a.CURRENT_DATE = d.CURRENT_DATE
) results ON total.CURRENT_DATE = results.CURRENT_DATE
ORDER BY CURRENT_DATE ASC; 

现在这个查询可以工作了,相对来说,它足够快,但看起来很丑。它看起来很难维护,而且我很确定我在这里遗漏了一些东西。

最佳答案

看起来您想要条件聚合:

SELECT TO_CHAR(SESSION_DATE, 'yyyy-mm-dd') as CURRENT_DATE,
       SUM(CASE WHEN PORTABLE_PEANUTS = 'RO' THEN 1 ELSE 0 END) as RO,
       SUM(CASE WHEN PORTABLE_PEANUTS = 'FL' THEN 1 ELSE 0 END) as FL,
       SUM(CASE WHEN PORTABLE_PEANUTS = 'LM' THEN 1 ELSE 0 END) as LM,
       SUM(CASE WHEN PORTABLE_PEANUTS = 'AO' THEN 1 ELSE 0 END) as AO,
       SUM(CASE WHEN PORTABLE_PEANUTS IN ('RO', 'FL', 'LM', 'AO') THEN 1 ELSE 0 END) as TOTAL           
FROM CORE.DATE_TEST
GROUP BY TO_CHAR(SESSION_DATE, 'yyyy-mm-dd')

我不确定你还想做什么。这实际上可能处理整个查询。

关于sql - Oracle SQL : Simplifying my seemingly-horrendous subquery collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33042228/

相关文章:

php - 获取相同日期的两个表的记录

c# - 在 C# 中化简分数

MySQLi 使用 CURDATE 检索 future 12 个月内事件的结果

sql - 如何选择所有列以及 Oracle 11g 中 CASE 语句的结果?

sql - 当我尝试更新 oracle 11 g 中的多个列时收到错误消息

oracle - Unitils 和 DBMaintainer - 如何使它们与多个用户/模式一起工作?

sql - 仅当其他表中某个字段的值数满足条件时才更新表中的列

database - 使用相同值更新主键时的性能影响

javascript - 简化 javascript if 语句,其中条件相同,但变量除外

optimization - 如何简化这段代码或者更好的设计?