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%')
;
Другие вопросы по тегам