2

Super simplified code:

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')
;

So the problem is that that last bit does not work (and I'm certain I am doing it wrong entirely, this was just one guess on how to do it.) I was wondering if someone could give me some suggestions.

What I am trying to do is only return the desired fields for cases in which the number of rows containing 'CRED' in a particular field are greater than the number of rows containing 'PUR' in a particular field. (The same field, if that can simplify things.) I would like them to be returned regardless of if 'CRED' or 'PUR' are part of longer words (credit/purchase) or stand alone. They will always be all caps though.

Edit:

What I'm looking for is just those columns I specified

| More_Stuff | Stuff | Things |
|   dshsdh   |  dfh  |  tjra  |
|   ddh      |  ash  |  ytra  |
|   shsdh    |  fgh  |  sayh  |
|   hsdh     |  gnh  |  tshn  |

but only the rows for the customers that have more credit codes than purchase plans. So if they have 3 different entries in 'c.things' with something like "PHONE-CREDIT" or "OFFSET CRED." and 2 different entries in 'c.things' with something like "12 M PURCH PLAN" or "PROMO PURCHASE 36", I want their info to show up. So, when the number of rows with any credit codes is greater than the number of rows with any purchase plans. My current non-simplified query is already set to sort through all customers, I just need to specify which ones based on this filter.

3 Answers3

0

I think you want something like this

 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)

Note: You can change the WHEN part to be whatever you want to count (eg WHEN field like '%PUR%' would count rows containing the string PUR

Also, I'm making an assumption of having no entries count as 0 -- your business rule for this case might be different.

Hogan
  • 69,564
  • 10
  • 76
  • 117
0

This can be achieved using WITH Clause in Oracle. The following code might be close to what you are looking for -

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
 ;
shrek
  • 887
  • 6
  • 12
  • what is all columns? – Hogan Mar 23 '18 at 17:44
  • It was more than just changing to a wildcard. Your answer does not get to the heart of what needs to be done or how. You don't join ds1 and ds2 for example -- as written you are doing a cross join of all rows. Fairly sure that isn't what he wants. – Hogan Mar 23 '18 at 19:53
  • As it stands if I try to use this I get a "group function not allowed" error. – RachaelTheBlonde Mar 23 '18 at 21:14
  • @Hogan - I agree its not accurate, my focus was more on giving the user an idea on how this can be implemented since the actual query is not posted here. – shrek Mar 23 '18 at 21:17
-1

To filter CRED and PUR in longer words use wildcards like % in the query.

like '%CRED%'  -- if CRED can be anywhere in the string
like 'CRED%'  -- if CRED is always at the beginning of the string

Note that if it is always at the beginning of the string, you can use an index on the column to make it run faster.

You cannot use an aggregate like count() in the where clause (unless Oracle supports it??)

You can group the rows and use HAVING but in your case, it is actually easier to move the count() inside the subqueries.

   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%')
;
Ghislain
  • 59
  • 3
  • how does this filter work? It does not relate to the selected tables A, B, or C. – Hogan Mar 23 '18 at 19:52
  • This is based on the example given in the question where the counts did not relate to other tables. Rows will be returned only if there are more CRED than PUR. If you want to look at CRED and PUR with more filters you need to add the filters to the sub queries. – Ghislain Mar 23 '18 at 20:42
  • I don't want to display what is in c.things, I just need to filter by it. I just want certain fields to show up for only those customers who have more credit codes than purchase plans. – RachaelTheBlonde Mar 23 '18 at 21:11
  • And just in case this is confusing, the alias for tables is not case sensitive. So table C is the same as table c; c.things is coming from table C. – RachaelTheBlonde Mar 23 '18 at 21:13
  • @Ghislain -- the example given in the question did not make any sense. your answer does not make any sense. Try a test and see what I mean. – Hogan Mar 23 '18 at 21:20
  • @RachaelTheBlonde --- that is what I did in my answer -- that is not what is being done here. – Hogan Mar 23 '18 at 21:21