将两个具有相似操作的查询组合到一个

时间:2017-04-24 22:08:32

标签: sql oracle

我在下面有一个查询,它给出了一个人走路时间超过2英里/小时的一年中总小时数与总条目数(查看的总小时数)的查询联合起来。两者基本上是相同的查询,除了第一个中的最后一个子句。问题是运行此查询需要30秒。有没有办法让我结合两个查询,使其运行得更快,但获得类似的数据?我的最终目标是获得一个人行走时间超过2英里/小时的百分比。

SELECT COUNT(STARTING_HOUR) FROM SENSOR.SPEED
FULL OUTER JOIN ACCOUNT.ID
ON SENSOR.SPEED.Account_ID = ACCOUNT.ID.Account_ID
FULL OUTER JOIN ACCOUNT.NAME
ON ACCOUNT.ID.Account_ID = ACCOUNT.NAME.Account_ID
WHERE UPPER(NAME) LIKE '%Sarah%'
AND UPPER(NAME) LIKE '%Jones%'
AND STARTING_HOUR >= TO_DATE('2015-01-01T00:00:00', 'YYYY-MM-
DD"T"HH24:MI:SS')
AND STARTING_HOUR <= TO_DATE('2015-12-31T00:00:00', 'YYYY-MM-
DD"T"HH24:MI:SS')
AND Value > 2

UNION

SELECT COUNT(STARTING_HOUR) FROM SENSOR.SPEED
FULL OUTER JOIN ACCOUNT.ID
ON SENSOR.SPEED.Account_ID = ACCOUNT.ID.Account_ID
FULL OUTER JOIN ACCOUNT.NAME
ON ACCOUNT.ID.Account_ID = ACCOUNT.NAME.Account_ID
WHERE UPPER(NAME) LIKE '%Sarah%'
AND UPPER(NAME) LIKE '%Jones%'
AND STARTING_HOUR >= TO_DATE('2015-01-01T00:00:00', 'YYYY-MM-DD"T"HH24:MI:SS')
AND STARTING_HOUR <= TO_DATE('2015-12-31T00:00:00', 'YYYY-MM-DD"T"HH24:MI:SS')

谢谢!

2 个答案:

答案 0 :(得分:1)

SELECT CASE
         WHEN COUNT(1) = 0   -- Handle division by zero
         THEN NULL
         ELSE COUNT( CASE WHEN value > 2 THEN 1 END )
              / COUNT( 1 )
       END AS Percentage
FROM   SENSOR.SPEED
       RIGHT OUTER JOIN ACCOUNT.NAME
       ON SENSOR.SPEED.Account_ID = ACCOUNT.NAME.Account_ID
WHERE  UPPER(NAME) LIKE '%SARAH%'
AND    UPPER(NAME) LIKE '%JONES%'
AND    STARTING_HOUR BETWEEN DATE '2015-01-01' AND DATE '2015-12-31'

您需要ACCOUNT.ID表吗?相反,您可以直接从SENSOR.SPEED加入ACCOUNT.NAME吗?

我假设NAME位于ACCOUNT.NAME,而UPPER(NAME)过滤器永远不会NULL,因此您可以执行RIGHT OUTER JOIN而不是FULL OUTER JOIN STARTING_HOUR。根据{{​​1}}列所在的表格,可以将其进一步简化为INNER JOIN

答案 1 :(得分:1)

首先,完全外连接完全是多余的。然后表别名使查询更容易编写和读取。然后你可以使用AVG()

进行算术运算
SELECT AVG(CASE WHEN VALUE > 2 THEN 1.0 ELSE 0 END)
FROM SENSOR.SPEED s JOIN
     ACCOUNT.ID i
     ON s.Account_ID = i.Account_ID JOIN
     ACCOUNT.NAME n
     ON i.Account_ID = n.Account_ID
WHERE UPPER(NAME) LIKE '%Sarah%' AND
      UPPER(NAME) LIKE '%Jones%' AND
      STARTING_HOUR >= DATE '2015-01-01' AND
      STARTING_HOUR <= DATE '2015-12-31' ;

我非常确定WHERE子句将所有外连接转换为内连接。也许你确实需要在某个地方进行外连接,但任何必要的都不是很明显。