Count Performance optimisation - performance

I got 2 versions of basically the same code. (See below) Version 1 is running at 2 seconds, version 2 is running at .5 - .6 seconds. There are 10 million rows currently from where I am selecting from, but this number goes up pretty fast. I would like to go even lower if possible. The problem is that I use Version 2, and I need to call that 30 times (different statuses, different usernames, etc), the final number is still going to be too big for what I need. Is there a 3rd version I could use instead? Or is there any other way I could make this to be even faster? Or the only thing that I could do is play with indexes.
Basically all these counts would be displayed in the most visited screen in a web application, and 30 * .5 seconds sounds a bit too much when 1000 users are using the system in the same time.
Version 1
declare #a1 datetime; set #a1 = GETDATE()
declare #int1 INT,#int2 INT,#int3 INT,#int4 INT,#int5 INT,#int6 INT,#int7 INT,#int8 INT
select #int1 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'a'
select #int2 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'b'
select #int3 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'c'
select #int4 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'd'
select #int5 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'e'
select #int6 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'f'
select #int7 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'g'
select #int8 = COUNT(Id) from ToDos where StatusId = 1 and stringUserId = 'h'
select #int1, #int2, #int3, #int4, #int5, #int6, #int7, #int8
SELECT DATEDIFF(MILLISECOND, #a1, GETDATE())
Version 2
declare #a1 datetime; set #a1 = GETDATE()
select stringUserId, count(stringUserId)
from ToDos
where StatusId = 1 and stringUserId in ('a','b','c','d','e','f','g','h')
group by stringUserId
order by COUNT(stringUserId) desc
SELECT DATEDIFF(MILLISECOND, #a1, GETDATE())

Try conditional count.
select
#int1 = COUNT(CASE WHEN stringUserId = 'a' THEN 1 END),
#int2 = COUNT(CASE WHEN stringUserId = 'b' THEN 1 END),
#int3 = COUNT(CASE WHEN stringUserId = 'c' THEN 1 END),
#int4 = COUNT(CASE WHEN stringUserId = 'd' THEN 1 END),
#int5 = COUNT(CASE WHEN stringUserId = 'e' THEN 1 END),
#int6 = COUNT(CASE WHEN stringUserId = 'f' THEN 1 END),
#int7 = COUNT(CASE WHEN stringUserId = 'g' THEN 1 END),
#int8 = COUNT(CASE WHEN stringUserId = 'h' THEN 1 END)
from ToDos
where StatusId = 1
FYI: I didnt include the ELSE part for CASE because for default will return NULL and COUNT doesnt count nulls

You could try:
select a.* from (select stringUserId, count(stringUserId) as IDCount
from ToDos
where StatusId = 1 and stringUserId in ('a','b','c','d','e','f','g','h')
group by stringUserId) a
order by a.IDCount desc
that eliminates the count function from the order by

Related

Conditional data selection in oracle

I have a set of data by using query and in this data I need to select some data according to following condition
If SIGNSTAT = 4 then select all row which have SIGNSTAT = 4
Otherwise select latest create date row data.
Please help to found the data
My query is as
WITH CTE AS(SELECT C2C.NO AS CONTRACTNO,
C.BRANCH,
C.IDCLIENT,
--C.PAN,
C.NAMEONCARD,
C.CREATEDATE,
C.SIGNSTAT,
ROW_NUMBER ()
OVER (PARTITION BY C2C.NO ORDER BY C.CREATEDATE DESC)
AS ROW_NUM
FROM A4M.TCONTRACTCARDITEM C2C, A4M.TCARD C,A4M.TREFERENCECARDPRODUCT RCP
WHERE 1 = 1 AND C.BRANCH = C2C.BRANCH AND C.PAN = C2C.PAN AND C2C.NO = '700000075333'
AND C.BRANCH = RCP.BRANCH AND C.CARDPRODUCT = RCP.CODE
AND UPPER(RCP.NAME) LIKE '%SUPPL%'
)
SELECT * FROM CTE
--WHERE ROW_NUM = 1
Result set:
CONTRACTNO BRANCH IDCLIENT NAMEONCARD CREATEDATE SIGNSTAT ROW_NUM
700000075333 1 1215995 SAMIR CHANDRA DHAR 14-Jul-19 4 2
700000075333 1 1215995 SAMIR CHANDRA DHAR 20-Aug-19 3 1
Is this what you need?
WITH data AS(SELECT C2C.NO AS CONTRACTNO,
C.BRANCH,
C.IDCLIENT,
--C.PAN,
C.NAMEONCARD,
C.CREATEDATE,
C.SIGNSTAT,
ROW_NUMBER ()
OVER (PARTITION BY C2C.NO ORDER BY C.CREATEDATE DESC)
AS ROW_NUM
FROM A4M.TCONTRACTCARDITEM C2C, A4M.TCARD C,A4M.TREFERENCECARDPRODUCT RCP
WHERE 1 = 1 AND C.BRANCH = C2C.BRANCH AND C.PAN = C2C.PAN AND C2C.NO = '700000075333'
AND C.BRANCH = RCP.BRANCH AND C.CARDPRODUCT = RCP.CODE
AND UPPER(RCP.NAME) LIKE '%SUPPL%'
), cnt AS (SELECT COUNT(1) total
FROM data
WHERE SIGNSTAT=4)
SELECT *
FROM data
WHERE SIGNSTAT=4
UNION ALL
SELECT *
FROM data
JOIN cnt
ON cnt.total=0
WHERE data.ROW_NUM = 1
I got the desire result by following query
WITH data AS(SELECT C2C.NO AS CONTRACTNO,
C.BRANCH,
C.IDCLIENT,
C.PAN,
C.NAMEONCARD,
C.CREATEDATE,
C.SIGNSTAT,
ROW_NUMBER ()
OVER (PARTITION BY C2C.NO ORDER BY C.CREATEDATE DESC)
AS ROW_NUM
FROM A4M.TCONTRACTCARDITEM C2C, A4M.TCARD C,A4M.TREFERENCECARDPRODUCT RCP
WHERE 1 = 1 AND C.BRANCH = C2C.BRANCH AND C.PAN = C2C.PAN AND C2C.NO = '700000075333'
AND C.BRANCH = RCP.BRANCH AND C.CARDPRODUCT = RCP.CODE
AND UPPER(RCP.NAME) LIKE '%SUPPL%') SELECT CONTRACTNO,BRANCH,IDCLIENT FROM data WHERE SIGNSTAT=4 UNION ALL (SELECT CONTRACTNO,BRANCH,IDCLIENT FROM data WHERE data.ROW_NUM = 1 MINUS SELECT CONTRACTNO,BRANCH,IDCLIENT FROM data WHERE SIGNSTAT=4)
You can achieve this with minor change in your original query. Use CASE WHEN as following:
WITH CTE AS(SELECT C2C.NO AS CONTRACTNO,
C.BRANCH,
C.IDCLIENT,
--C.PAN,
C.NAMEONCARD,
C.CREATEDATE,
C.SIGNSTAT,
CASE WHEN C.SIGNSTAT = 4 THEN 1 ELSE ROW_NUMBER ()
OVER (PARTITION BY C2C.NO ORDER BY C.CREATEDATE DESC) END
AS ROW_NUM
FROM A4M.TCONTRACTCARDITEM C2C, A4M.TCARD C,A4M.TREFERENCECARDPRODUCT RCP
WHERE 1 = 1 AND C.BRANCH = C2C.BRANCH AND C.PAN = C2C.PAN AND C2C.NO = '700000075333'
AND C.BRANCH = RCP.BRANCH AND C.CARDPRODUCT = RCP.CODE
AND UPPER(RCP.NAME) LIKE '%SUPPL%'
)
SELECT * FROM CTE
WHERE ROW_NUM = 1
Cheers!!

Count and Sum inside a select with multiple sums and counts

I'm using sub-query factoring and I have a query that returns invoice lines, and in the end I have this final sub-query:
I've already tried Partition but without success
SELECT
COUNT(CASE WHEN PC <> 0 THEN 1 END) AS A_LINECOUNT,
SUM(CASE WHEN PC > 0 THEN NR ELSE 0 END) AS B_PRODUCTCOUNT,
COUNT(CASE WHEN ALLOW_PAY = 1 THEN 1 END) AS C_INVOICECOUNT, --- ERROR
SUM(CASE WHEN ALLOW_PAY = 1 THEN MISSING_VALUE ELSE 0 END) AS D_INVOICETOTAL, --- ERROR
COUNT(CASE WHEN IS_NON_LIQUIDABLE_PRODUCT = 1 THEN 1 END) AS E_CONDITIONCOUNT,
COUNT(CASE WHEN IS_LIQUIDABLE_PRODUCT = 1 THEN 1 END) AS F_CONDITIONCOUNT
FROM MAIN_Q
The calculation of C_INVOICECOUNT and D_INVOICETOTAL is not correct because their values are repeated within each line of the invoice. Please consider that um MAIN_Q i also have a document_id where i can group by.
thanks
Maybe I understood correctly, maybe not, but this is too long for comment. If yes, C_INVOICECOUNT can be count as:
count(distinct case when allow_pay = 1 then document_id end)
But the problem is with D_INVOICETOTAL. You have repeated values for each invoice here and details which do not repeat. If so, add row numbering to your query:
select main_q.*, row_number() over (partition by document_id) rn from main_q
and then in problematic places use rn = 1:
select ...
count(case when rn = 1 and allow_pay = 1 then 1 end),
sum(case when rn = 1 and allow_pay = 1 then missing_value else 0 end)
...
from (select main_q.*, row_number() over (partition by document_id) rn from main_q)
Only first rows for each invoice will be analysed. Of course you can add row_number in earlier step.

WITH Clause no longer working. "exceeded call limit on IO usage"

I have some code that previously ran fine with no issues. But now when I run I receive the
ORA-02395: exceeded call limit on IO usage
02395. 00000 - "exceeded call limit on IO usage"
error. Can anyone explain to me why my code is throwing this error. I have no access to increase any user privileges. I've tried running this code and limiting the amount of data in the with clause and it ran fine. So I'm guessing some modifications need to happen there.
WITH NEW_REP_DATA AS (
select period,manager rep,comp,sum(a) "GT99",sum(b) "90TO99",sum(c) "80TO89",sum(d) "70TO79",sum(e) "LT70",sum(f) "NA" from (
select period
,rep_code
,manager
--,nvl(a,0)+nvl(b,0)+nvl(c,0)+nvl(d,0)+nvl(e,0)+nvl(f,0) cnt
,comp,
nvl(a,0) a,nvl(b,0) b, nvl(c,0) c, nvl(d,0) d,nvl(e,0) e,nvl(f,0) f
from
(select period,rep_code,manager, comp,max(case when bucket='>99' then cnt end) a,
max(case when bucket='90TO99' then cnt end) b,
max(case when bucket='80TO89' then cnt end) c,
max(case when bucket= '70TO79' then cnt end) d,
max(case when bucket='LT70' then cnt end) e,
max(case when bucket='NA' then cnt end) f
from (
select period,rep_code,manager, comp,bucket,
--count(unique rep_code)
count( distinct rep_code) cnt
--cnt
from(
select * from (select
unique period
,MANAGER
,"PayeeID" rep_code
,comp
,cytd cytd_a
,cytp cytd_p,
nvl(case when cytp > 0 then
case when round((cytd/cytp),3) > .99 then '>99'
when round((cytd/cytp),3) between .891 and .99 then '90TO99'
when round((cytd/cytp),3) between .791 and .89 then '80TO89'
when round((cytd/cytp),3) between .7 and .79 then '70TO79'
when round((cytd/cytp),3) < .7 then 'LT70'
end
when cytp = 0 and cytd > 0 then '>99'
else 'NA'
end,'NA') as bucket
from (
select aaa.period
,aaa."PayeeID"
,aaa."Reports_to" MANAGER
,aaa."Component" comp,
aaa."Current_YTD_Actual" cytd,
aaa."Current_YTD_Plan" cytp
from nbr_var_data aaa
where aaa."Comp_Plan_Name" not in ('MISC_COMP','GM_2017')
AND "Comp_Plan_Name" not in ('MISC_COMP')
AND "Comp_Plan_Name" not LIKE '%GM%'
and aaa.period = (select max(aaa.period) from Nbr_Var_Data)
))
)
where 1=1
group by period, rep_code, comp, bucket, manager )
group by period, rep_code, comp, manager )) group by period, manager, comp)
SELECT DISTINCT
dc.rep PID
,dc.period
,ee.PAYEE_NAM
,dc.comp
,Dc."GT99"
,Dc."90TO99"
,Dc."80TO89"
,Dc."70TO79"
,Dc."LT70"
,Dc."NA"
,Ee.Parent_Payee_Id REPORT_TO_PAYEE_ID
,Ee.Parent_Payee_Nam REPORT_TO_NAME
FROM (SELECT
--period ,
--empl_id ,
gg.payee_id ,
gg.payee_nam ,
--lvl ,
ff.parent_payee_id ,
ff.PARENT_PAYEE_NAM
--parent_lvl ,
--mnth_disp
FROM (SELECT DISTINCT
dd.period
,dd.PARENT_PAYEE_ID
,ee.PAYEE_NAM PARENT_PAYEE_NAM
from (
SELECT DISTINCT
PERIOD,
PARENT_PAYEE_ID
FROM FI_CHANNEL_HIER) dd
left join FI_CHANNEL_HIER ee
on dd.PARENT_PAYEE_ID = ee.PAYEE_ID
WHERE DD.PERIOD = (select max(DD.PERIOD) from FI_CHANNEL_HIER )) ff
LEFT JOIN FI_CHANNEL_HIER gg
ON ff.PARENT_PAYEE_ID = gg.PARENT_PAYEE_ID) ee,
NEW_REP_DATA dc
WHERE EE.PAYEE_ID = DC.Rep
;
ORA-02395 happens when your query exceeds the LOGICAL_READS_PER_CALL threshold set in your user profile. That's why the issue goes away when you restricted the amount of data returned by your subquery.
Two possible explanations for why this did not use to happen:
The tables contain more data than they used to be.
Your DBA has implemented a new user profile (or made the existing one stricter).
The obvious solution is to negotiate with the DBA.
Otherwise you will need to refactor your query to reduce the number of blocks it scans. Doing requires an understanding of your data model, your business logic and your data characteristics (volume, distribution, usage).
Clearly that requires knowledge of and access to your system, so it's not something that we can help with.
WITH NEW_REP_DATA AS (
select period,manager rep,comp,sum(a) "GT99",sum(b) "90TO99",sum(c) "80TO89",sum(d) "70TO79",sum(e) "LT70",sum(f) "NA" from (
select period
,rep_code
,manager
--,nvl(a,0)+nvl(b,0)+nvl(c,0)+nvl(d,0)+nvl(e,0)+nvl(f,0) cnt
,comp,
nvl(a,0) a,nvl(b,0) b, nvl(c,0) c, nvl(d,0) d,nvl(e,0) e,nvl(f,0) f
from
(select period,rep_code,manager, comp,max(case when bucket='>99' then cnt end) a,
max(case when bucket='90TO99' then cnt end) b,
max(case when bucket='80TO89' then cnt end) c,
max(case when bucket= '70TO79' then cnt end) d,
max(case when bucket='LT70' then cnt end) e,
max(case when bucket='NA' then cnt end) f
from (
select period,rep_code,manager, comp,bucket,
--count(unique rep_code)
count( distinct rep_code) cnt
--cnt
from(
select * from (select
unique period
,MANAGER
,"PayeeID" rep_code
,comp
,cytd cytd_a
,cytp cytd_p,
nvl(case when cytp > 0 then
case when round((cytd/cytp),3) > .99 then '>99'
when round((cytd/cytp),3) between .891 and .99 then '90TO99'
when round((cytd/cytp),3) between .791 and .89 then '80TO89'
when round((cytd/cytp),3) between .7 and .79 then '70TO79'
when round((cytd/cytp),3) < .7 then 'LT70'
end
when cytp = 0 and cytd > 0 then '>99'
else 'NA'
end,'NA') as bucket
from (
select aaa.period
,aaa."PayeeID"
,aaa."Reports_to" MANAGER
,aaa."Component" comp,
aaa."Current_YTD_Actual" cytd,
aaa."Current_YTD_Plan" cytp
from nbr_var_data aaa
where aaa."Comp_Plan_Name" not in ('MISC_COMP','GM_2017')
AND "Comp_Plan_Name" not in ('MISC_COMP')
AND "Comp_Plan_Name" not LIKE '%GM%'
and aaa.period = (select max(aaa.period) from Nbr_Var_Data)
))
)
where 1=1
group by period, rep_code, comp, bucket, manager )
group by period, rep_code, comp, manager )) group by period, manager, comp)
SELECT DISTINCT
dc.rep PID
,dc.period
,ee.PAYEE_NAM
,dc.comp
,Dc."GT99"
,Dc."90TO99"
,Dc."80TO89"
,Dc."70TO79"
,Dc."LT70"
,Dc."NA"
,Ee.Parent_Payee_Id REPORT_TO_PAYEE_ID
,Ee.Parent_Payee_Nam REPORT_TO_NAME
FROM (SELECT
--period ,
--empl_id ,
gg.payee_id ,
gg.payee_nam ,
--lvl ,
ff.parent_payee_id ,
ff.PARENT_PAYEE_NAM
--parent_lvl ,
--mnth_disp
FROM (SELECT DISTINCT
dd.period
,dd.PARENT_PAYEE_ID
,ee.PAYEE_NAM PARENT_PAYEE_NAM
from (
SELECT DISTINCT
PERIOD,
PARENT_PAYEE_ID
FROM FI_CHANNEL_HIER) dd
left join FI_CHANNEL_HIER ee
on dd.PARENT_PAYEE_ID = ee.PAYEE_ID
WHERE DD.PERIOD = (select max(DD.PERIOD) from FI_CHANNEL_HIER )) ff
LEFT JOIN FI_CHANNEL_HIER gg
ON ff.PARENT_PAYEE_ID = gg.PARENT_PAYEE_ID) ee,
NEW_REP_DATA dc
WHERE EE.PAYEE_ID = DC.Rep
AND dc.period = (select max(period) from NEW_REP_DATA)
;

oracle SQL procedure updating table

I need to update the the following columns in a table. males,females,infants and children using SQL procedure.from this column paxtype which has f,i,m,c.which is females,infants,males and children repectively.but am not able error ORA-00907: missing right parenthesis
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT b.PAXTYPE, COUNT (b.PAXTYPE) FROM xxxx b
(case ( count (b.PAXTYPE))
when ( count (b.PAXTYPE))='M'then 'a.males'
when ( count (b.PAXTYPE))='F' then 'a.females'
when ( count (b.PAXTYPE))='I' then 'a.infants'
when ( count (b.PAXTYPE))='C' then 'a.children'
END)
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE;
)
It looks like you want a total count of each type, right? I think this is what you want to do.
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT
sum(case when b.PAXTYPE = 'I' then 1 else 0 end) as infants_count,
sum(case when b.PAXTYPE = 'M' then 1 else 0 end) as males_count,
sum(case when b.PAXTYPE = 'C' then 1 else 0 end) as children_count,
sum(case when b.PAXTYPE = 'F' then 1 else 0 end) as females_count
FROM xxxx b
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE);

Oracle/SQL Query issue

I am sort of a newbie to oracle/sql. I am trying to pull from the same column different values and add them with some other information. The other information is not the issue it is trying to count and add here the problem comes in.
I am connecting to an oracle database. Here is what i have
SELECT
EV.PUBLIC_DESCRIPTION,
EV.EVENT_DATE,
ES.PRICE,
BT.BUYER_TYPE_CODE,
PCA.ADDR1,
PCA.ADDR2,
PCA.CITY,
PCA.POSTAL_CODE,
PCE.EMAIL,
PC.FORMATTED_NAME,
PCP.PHONE_NUMBER,
PCP.SECONDARY,
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADLT' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADTE' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GSTDTE' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GROUDI' THEN 1 ELSE 0 END)) AS "Adults",
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCHILD' THEN 1 ELSE 0 END) + COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCHTE' THEN 1 ELSE 0 END)) AS 'Paid Child',
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRPCH' THEN 1 ELSE 0 END)) AS 'Free Child',
SUM(COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCOMP' THEN 1 ELSE 0 END)) AS 'Comps'
FROM EVENT EV
INNER JOIN EVENT_SEAT ES ON EV.EVENT_ID = ES.EVENT_ID
INNER JOIN BUYER_TYPE BT ON ES.BUYER_TYPE_ID = BT.BUYER_TYPE_ID
INNER JOIN PATRON_ORDER PO ON ES.ORDER_ID = PO.ORDER_ID
INNER JOIN PATRON_ACCOUNT PA ON ES.ATTENDING_PATRON_ACCOUNT_ID = PA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT PC ON PA.PATRON_ACCOUNT_ID = PC.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_ADDRESS PCA ON PC.PATRON_ACCOUNT_ID = PCA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_EMAIL PCE ON PCA.PATRON_ACCOUNT_ID = PCE.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_PHONE PCP ON PCE.PATRON_ACCOUNT_ID = PCP.PATRON_ACCOUNT_ID
GROUP BY EV.PUBLIC_DESCRIPTION, EV.EVENT_DATE
ORDER BY ES.TRANSACTION_ID DESC, PCP.SECONDARY DESC, PCP.PHONE_NUMBER DESC, PC.FORMATTED_NAME DESC, PCE.EMAIL DESC, PCA.POSTAL_CODE DESC, PCA.CITY DESC, PCA.ADDR2 DESC, PCA.ADDR1 DESC, BT.BUYER_TYPE_CODE DESC, ES.PRICE DESC;
any help would be greatly appreciated
You need to decide which technique you want to use, currently you are using 2 techniques and they are colliding.
For this you must know: COUNT() will increment by one for every NON-NULL value
So, to use COUNT() with a case expression do this
COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 END)
or
COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE NULL END)
OR, don't use COUNT(), use SUM() instead
SUM(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 ELSE 0 END)
To add conditions together, I suggest you use the case expression better
Instead of something like this:
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADLT' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRADTE' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRSTND' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GSTDTE' THEN 1 END)
+ COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GROUDI' THEN 1 END) AS "Adults"
Use this:
COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRADLT','GRADTE','GRSTND','GSTDTE','GROUDI') THEN 1 ELSE NULL END)
There is also an issue with your GROUP BY, which MUST contain ALL non-aggregating columns. I think your query should look more like this:
SELECT
EV.PUBLIC_DESCRIPTION
, EV.EVENT_DATE
, ES.PRICE
/* , BT.BUYER_TYPE_CODE */
, PCA.ADDR1
, PCA.ADDR2
, PCA.CITY
, PCA.POSTAL_CODE
, PCE.EMAIL
, PC.FORMATTED_NAME
, PCP.PHONE_NUMBER
, PCP.SECONDARY
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRADLT', 'GRADTE', 'GRSTND', 'GSTDTE', 'GROUDI') THEN 1 ELSE NULL END) AS "Adults"
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE IN ('GRCHILD', 'GRCHTE', 'GRPCH', 'GRCOMP') THEN 1 ELSE NULL END) AS "Free Child"
, COUNT(CASE WHEN BT.BUYER_TYPE_CODE = 'GRCOMP' THEN 1 ELSE NULL END) AS "Comps"
FROM EVENT EV
INNER JOIN EVENT_SEAT ES
ON EV.EVENT_ID = ES.EVENT_ID
INNER JOIN BUYER_TYPE BT
ON ES.BUYER_TYPE_ID = BT.BUYER_TYPE_ID
INNER JOIN PATRON_ORDER PO
ON ES.ORDER_ID = PO.ORDER_ID
INNER JOIN PATRON_ACCOUNT PA
ON ES.ATTENDING_PATRON_ACCOUNT_ID = PA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT PC
ON PA.PATRON_ACCOUNT_ID = PC.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_ADDRESS PCA
ON PC.PATRON_ACCOUNT_ID = PCA.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_EMAIL PCE
ON PCA.PATRON_ACCOUNT_ID = PCE.PATRON_ACCOUNT_ID
INNER JOIN PATRON_CONTACT_PHONE PCP
ON PCE.PATRON_ACCOUNT_ID = PCP.PATRON_ACCOUNT_ID
GROUP BY
EV.PUBLIC_DESCRIPTION
, EV.EVENT_DATE
, ES.PRICE
/* , BT.BUYER_TYPE_CODE */
, PCA.ADDR1
, PCA.ADDR2
, PCA.CITY
, PCA.POSTAL_CODE
, PCE.EMAIL
, PC.FORMATTED_NAME
, PCP.PHONE_NUMBER
, PCP.SECONDARY
/* check all these columns exist in the select clause
ORDER BY
ES.TRANSACTION_ID DESC
, PCP.SECONDARY DESC
, PCP.PHONE_NUMBER DESC
, PC.FORMATTED_NAME DESC
, PCE.EMAIL DESC
, PCA.POSTAL_CODE DESC
, PCA.CITY DESC
, PCA.ADDR2 DESC
, PCA.ADDR1 DESC
, BT.BUYER_TYPE_CODE DESC
, ES.PRICE DESC
*/
When you come the the final clause: ORDER BY you can ONLY reference columns that exist in the select clause. This example would FAIL
select column1 from table1 group by column1 order by fred
but this would work:
select column1 from table1 group by column1 order by column1
Your column aliases 'Paid Child', 'Free Child', 'Comps' should not be wrapped in single quotes. You should be using double quotes like you are already for "Adults".
So they should instead be:
"Paid Child"
"Free Child"
"Comps"
Or better yet, consider naming your aliases without any spaces, so you don't have to worry about wrapping the aliases in anything, like this:
paid_child
free_child
comps
Documentation on Database Object Names and Qualifiers:
Database Object Naming Rules
Every database object has a name. In a SQL statement, you represent the name of an object with a quoted identifier or a nonquoted identifier.
A quoted identifier begins and ends with double quotation marks ("). If you name a schema object using a quoted identifier, then you must use the double quotation marks whenever you refer to that object.
A nonquoted identifier is not surrounded by any punctuation.
...
Although column aliases, table aliases, usernames, and passwords are not objects or parts of objects, they must also follow these naming rules unless otherwise specified in the rules themselves.

Resources