У меня есть запрос ниже, который дает мне общее количество часов в году, когда человек идет со скоростью более 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 ответа
Во-первых, полное внешнее соединение совершенно излишне. Затем псевдонимы таблиц облегчают написание и чтение запроса. И тогда вы можете сделать арифметику, используя 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
превращают все внешние объединения во внутренние. Возможно, вы хотите где-нибудь внешнее соединение, но не очевидно, что оно необходимо.
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
вместо {{X5 } } . В зависимости от того, в какой таблице находится столбец STARTING_HOUR
, это может быть дополнительно упрощено до INNER JOIN
.
Новые вопросы
sql
Язык структурированных запросов (SQL) - это язык запросов к базам данных. Вопросы должны включать примеры кода, структуру таблицы, примеры данных и тег для используемой реализации СУБД (например, MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2 и т. Д.). Если ваш вопрос относится исключительно к конкретной СУБД (использует определенные расширения / функции), используйте вместо этого тег этой СУБД. Ответы на вопросы, помеченные SQL, должны использовать стандарт ISO / IEC SQL.