SQL - использовать результаты запроса в качестве основы для двух других запросов в одном операторе - PullRequest
1 голос
/ 15 января 2009

Я делаю расчет вероятности. У меня есть запрос для расчета общего числа случаев, когда событие происходит. Из этих событий я хочу узнать, сколько раз происходит подэвент. Запрос для получения общего количества событий составляет 25 строк, и я не хочу просто копировать + вставлять его дважды.

Я хочу сделать с этим запросом две вещи: вычислить количество строк в нем и вычислить количество строк в результате запроса по этому запросу. Сейчас я могу думать только об этом (замените @ total @ сложным запросом для получения всех строк, а @ condition @ - менее сложными условиями, которым должны соответствовать строки из @ total @ подэвент):

SELECT (SELECT COUNT(*) FROM (@total@) AS t1 WHERE @conditions@) AS suboccurs, 
       COUNT(*) AS totaloccurs FROM (@total@) as t2

Как вы заметили, @ total @ повторяется дважды. Есть ли способ обойти это? Есть ли лучший способ сделать то, что я пытаюсь сделать?

Чтобы еще раз подчеркнуть: @ условие @ зависит от того, что @ total @ возвращает (это такие вещи как t1.foo = bar).

Несколько заключительных замечаний: @ total @ само по себе занимает ~ 250 мс. Этот более сложный запрос занимает ~ 300 мс, поэтому postgres, вероятно, сам выполняет некоторую оптимизацию. Тем не менее, запрос выглядит ужасно уродливо, когда @ total @ буквально вставлен дважды.

Ответы [ 4 ]

6 голосов
/ 15 января 2009

Если ваш sql поддерживает факторинг подзапроса, то переписать его с помощью оператора WITH можно. Это позволяет использовать подзапросы более одного раза. Он создаст их в Oracle как встроенное представление или временную таблицу.

Вот надуманный пример.

WITH
x AS
(
    SELECT this
    FROM THERE
    WHERE something is true
),
y AS
(
    SELECT this-other-thing
    FROM somewhereelse
    WHERE something else is true
), 
z AS
(
    select count(*) k
    FROM X
)
SELECT z.k, y.*, x.*
FROM x,y, z
WHERE X.abc = Y.abc
1 голос
/ 15 января 2009
SELECT COUNT(*) as totaloccurs, COUNT(@conditions@) as suboccurs
FROM (@total@ as t1)
0 голосов
/ 15 января 2009

@ EvilTeach:

Я не видел "с" (возможно, не реализовано в Sybase :-(). Мне нравится: делает то, что вам нужно в одном чанке, затем уходит, с еще меньшими затратами, чем временные таблицы. Классно. *

0 голосов
/ 15 января 2009

Поместите повторно используемый подзапрос во временную таблицу, затем выберите то, что вам нужно, из временной таблицы.

...