SQL-запрос; как отображать информацию только там, где количество записей в одной строке больше, чем количество записей в другой?
Супер упрощенный код:
SELECT lots_of_stuff.
, A.more_stuff
, B.stuff
, C.things
FROM
table A,
table B,
table C,
where (B.more_stuff = A.stuff)
and things and stuff
and lots more things
and this query has so much crap believe me
and finally
and count(select c.things from table C where c.things like 'CRED')
> count(select c.things from table C where c.things like 'PUR')
;
Так что проблема в том, что этот последний бит не работает (и я уверен, что я делаю это неправильно, это была всего лишь одна догадка о том, как это сделать.) Мне было интересно, может ли кто-нибудь дать мне несколько советов.
То, что я пытаюсь сделать, - это вернуть нужные поля только в тех случаях, когда количество строк, содержащих "CRED" в определенном поле, превышает количество строк, содержащих "PUR" в конкретном поле. (То же поле, если это может упростить вещи.) Я хотел бы, чтобы они были возвращены независимо от того, являются ли слова "CRED" или "PUR" частью более длинных слов (кредит / покупка) или являются самостоятельными. Они всегда будут все заглавными буквами, хотя.
Редактировать:
Я ищу только те столбцы, которые я указал
| More_Stuff | Stuff | Things |
| dshsdh | dfh | tjra |
| ddh | ash | ytra |
| shsdh | fgh | sayh |
| hsdh | gnh | tshn |
но только строки для клиентов, которые имеют больше кредитных кодов, чем планов покупки. Так что если у них есть 3 разных записи в "c.things" с чем-то вроде "PHONE-CREDIT" или "OFFSET CRED". и 2 разных записи в "c.things" с чем-то вроде "12 M PURCH PLAN" или "PROMO PURCHASE 36", я хочу, чтобы их информация отображалась. Таким образом, когда число строк с любыми кредитными кодами превышает количество строк с любыми планами закупок. Мой текущий неупрощенный запрос уже настроен на сортировку всех клиентов, мне просто нужно указать, какие из них основаны на этом фильтре.
3 ответа
Я думаю, что вы хотите что-то подобное
WITH cred_count AS
(
SELECT index_field, SUM(CASE WHEN field='CRED' THEN 1 ELSE 0 END) AS cred_count
FROM some_table
GROUP BY index_field
), pur_count AS
(
SELECT index_field, SUM(CASE WHEN field='PUR' THEN 1 ELSE 0 END) AS pur_count
FROM some_table
GROUP BY index_field
)
SELECT somestuff
FROM some_table
LEFT JOIN cred_count ON some_table.index_field = cred_count.index_field
LEFT JOIN pur_count ON some_table.index_field = pur_count.index_field
WHERE COALESCE(cred_count.cred_count,0) > COALESCE(pur_count.pur_count,0)
Примечание: вы можете изменить часть КОГДА на то, что вы хотите считать (например, WHEN field like '%PUR%'
будет считать строки, содержащие строку PUR
Кроме того, я предполагаю, что ни одна запись не считается 0 - ваше бизнес-правило для этого случая может быть другим.
Это может быть достигнуто с помощью предложения WITH в Oracle. Следующий код может быть близок к тому, что вы ищете -
with ds1 as
(
SELECT
lots_of_stuff
, A.more_stuff
, B.stuff
, C.things,
count(c.things) AS COUNT_CRED
FROM
table A,
table B,
table C,
where
(B.more_stuff = A.stuff)
and things and stuff
and lots more things
and this query has so much crap believe me
and finally
and c.things like 'CRED%'
group by
lots_of_stuff.
, A.more_stuff
, B.stuff
, C.things
),
ds2 as
(
SELECT
lots_of_stuff.
, A.more_stuff
, B.stuff
, C.things,
count(c.things) AS COUNT_PUR
FROM
table A,
table B,
table C,
where
(B.more_stuff = A.stuff)
and things and stuff
and lots more things
and this query has so much crap believe me
and finally
and c.things like 'PUR%'
group by
lots_of_stuff.
, A.more_stuff
, B.stuff
, C.things
)
SELECT DS1.*, ds2.*
from ds1, ds2
where count_cred > COUNT_PUR
;
Для фильтрации CRED и PUR в более длинных словах используйте подстановочные знаки, такие как% в запросе.
like '%CRED%' -- if CRED can be anywhere in the string
like 'CRED%' -- if CRED is always at the beginning of the string
Обратите внимание, что если он всегда находится в начале строки, вы можете использовать индекс для столбца, чтобы он работал быстрее.
Вы не можете использовать агрегат наподобие count() в предложении where (если Oracle его не поддерживает??)
Вы можете сгруппировать строки и использовать HAVING, но в вашем случае на самом деле легче перемещать count() внутри подзапросов.
SELECT lots_of_stuff.
, A.more_stuff
, B.stuff
, C.things
FROM
table A,
table B,
table C,
where (B.more_stuff = A.stuff)
and things and stuff
and lots more things
and this query has so much crap believe me
and finally
and (select count(c.things) from table C where c.things like '%CRED%')
> (select count(c.things) from table C where c.things like '%PUR%')
;