I am having an issue with a Case Statement, this is being used in a Saved Search for Netsuite but the reporting DB runs off Oracle. We are calculating Net Promoter Score (NPS) based on a question from our Customer Surveys. Below is a working example:
SUM(Case When {custrecord_rsm_csf_rec} = 'Very Likely' Then 1 Else 0 End -
Case When {custrecord_rsm_csf_rec} = 'Neither Likely or Unlikely' Then 1
When {custrecord_rsm_csf_rec} = 'Unlikely' then 1
When {custrecord_rsm_csf_rec} = 'Very Unlikely' then 1 Else 0 End)
/count({internalid})
What I am trying to do is add the to_char({created}), 'MM') = xx to group the results in month to month buckets on the returned result. I have am having no luck after many different attempts that all look something like below:
SUM(Case When {custrecord_rsm_csf_rec} = 'Very Likely' AND
to_char({created}), 'MM') = 03 Then 1 Else 0 End -
Case When {custrecord_rsm_csf_rec} = 'Neither Likely or Unlikely' AND
to_char({created}), 'MM') = 03 Then 1
When {custrecord_rsm_csf_rec} = 'Unlikely' AND to_char({created}), 'MM') =
03 then 1
When {custrecord_rsm_csf_rec} = 'Very Unlikely' AND to_char({created}),
'MM') = 03 then 1 Else 0 End)
/count({internalid})
Any assistance pointing me toward my Syntax/Logical errors would be much appreciated.
Related
I am trying to implement a code that filters the number of customers who have checked more books than DVDs in a library. The query is supposed to display the customer name, total book checkouts and total DVD checkouts.
ERD with all the tables
Here is my code that counts the total book checkouts and total DVD checkouts.
SELECT C.CUSTOMER_FIRSTNAME||' '|| C.CUSTOMER_LASTNAME "CUSTOMER
NAME",COUNT(*)"TOTAL CHECKOUTS"
FROM CATALOG_ITEM CI
JOIN PHYSICAL_ITEM PI
ON CI.CATALOG_ITEM_ID = PI.CATALOG_ITEM_ID
JOIN TRANSACTION TI
ON PI.PHYSICAL_ITEM_ID = TI.PHYSICAL_ITEM_ID
JOIN LIBRARY_CARD LC
ON TI.LIBRARY_CARD_ID = LC.LIBRARY_CARD_ID
JOIN CUSTOMER C
ON LC.CUSTOMER_ID = C.CUSTOMER_ID
GROUP BY C.CUSTOMER_FIRSTNAME||' '|| C.CUSTOMER_LASTNAME,CI.TYPE;
I finally solved my problem. Using COUNT(CASE WHEN field = 'record' THEN 1 END), I was able to specify the record to be counted on each column.
SELECT C.CUSTOMER_FIRSTNAME ||' '||C.CUSTOMER_LASTNAME "CUSTOMER NAME",
COUNT(CASE WHEN CI.TYPE = 'BOOK' THEN 1 END)"TOTAL BOOK CHECKOUTS",
COUNT(CASE WHEN CI.TYPE = 'DVD' THEN 1 END)"TOTAL DVD CHECKOUTS"
FROM CATALOG_ITEM CI
JOIN PHYSICAL_ITEM PI
ON CI.CATALOG_ITEM_ID = PI.CATALOG_ITEM_ID
JOIN TRANSACTION TI
ON PI.PHYSICAL_ITEM_ID = TI.PHYSICAL_ITEM_ID
JOIN LIBRARY_CARD LI
ON TI.LIBRARY_CARD_ID = LI.LIBRARY_CARD_ID
JOIN CUSTOMER C
ON LI.CUSTOMER_ID = C.CUSTOMER_ID
GROUP BY C.CUSTOMER_FIRSTNAME ||' '||C.CUSTOMER_LASTNAME
HAVING COUNT(CASE WHEN CI.TYPE = 'BOOK' THEN 1 END) > COUNT(CASE WHEN CI.TYPE =
'DVD' THEN 1 END)
ORDER BY C.CUSTOMER_FIRSTNAME ||' '||C.CUSTOMER_LASTNAME;
Any alternative solution will be appreciated.
is't possible to set 2 counts in the same row.
my result from query is like this:
enter image description here
and i will that the end result seem like this :
enter image description here
and at the end build the precent count1 to count2
my attempt trough case was not successful : SELECT Date,Shift , CASE description WHEN 'Defects' THEN count ELSE 0 END AS Defect_Count , CASE description WHEN 'Total' THEN count ELSE 0 END AS Total_Count FROM ("Queries union)
Here you go. Hope this helps. Thanks.
MYSQL:
select
t.dates, t.shift,
sum(case when t.description = 'Defects' then t.counts else 0 end) as `Defects`,
sum(case when t.description = 'Total' then t.counts else 0 end) as `Total`
from (
select *
from tbl ) t
group by t.dates, t.shift
order by t.dates, t.shift
ORACLE:
SELECT dates, shift, defects , total
FROM
(
SELECT *
FROM tbl
)
PIVOT
(
sum(counts)
FOR description IN ('Defects' as defects, 'Total' as total)
)
ORDER BY dates
Result:
dates shift Defects Total
2018-01-20 AM 21 56
2018-01-20 PM 19 54
2018-01-23 AM 16 58
2018-01-23 PM 20 45
many Thanks is working for the first Step (counts in the same Row).
i will try now to build the percent (Defects to Total).
Thanks.
to build the percent (defects to Total):
select dates,shift,defects,total,round((100*defects/total),2) Percent2Total from(select t.dates, t.shift,
sum(case when t.description = 'Defects' then t.counts else 0 end) as 'Defects',
sum(case when t.description = 'total' then t.counts else 0 end) as 'Total'
from (
select *
from tbl ) t
group by t.dates, t.shift
)q order by dates,Shift.
may be it's possible to build that only with Pivot or?
How can I change the way my output comes back to get it all on one line? Right now if has 2 lines. RA equals 1KK8888 in both, and the fee in one line and the Rate in the secound line.
select
,FRP.rent_doc_cd as Contract
,case when charge.charge_id = 7213 then charge.chg_amt else 0 end as FEE
,case when charge.charge_id = 7220 then charge.chg_amt else 0 end as Rate
FROM intgX.RENTAL_Tbl FRP
left join intgX.RENTAL_CHG charge on FRP.renalt_document = charge.rental_document and charge.charge_cd in (7213,7220)
where FRP.renalt_chg = '1KK8888'
This is usually done by adding MAX plus GROUP BY:
select
,FRP.rent_doc_cd as Contract
,max(case when charge.charge_id = 7213 then charge.chg_amt else 0 end) as FEE
,max(case when charge.charge_id = 7220 then charge.chg_amt else 0 end) as Rate
FROM intgX.RENTAL_Tbl FRP
left join intgX.RENTAL_CHG charge on FRP.renalt_document = charge.rental_document and charge.charge_cd in (7213,7220)
where FRP.renalt_chg = '1KK8888'
group by 1
I have written the following statement which doesn't work because of the In clause i've added. Can someone help suggest a workable solution?
What I want to do is measure the min/max values of grades for each record key. Some have more than one grade so thats why I've added the In clause so it will factor this?
case when MIN("Grade - Current"."Grade Equivalency")=MIN("Grade - Current"."Grade Equivalency")
IN (People." Record Key") then 'y' else 'n' end
The data in the table looks like this:
RecordKey Version Grade
165 2009 1
165 2012 2
175 2009 1
189 2012 1
200 2009 2
200 2012 1
You already have a Boolean condition:
"MIN("Grade - Current"."Grade Equivalency")=MIN("Grade - Current"."Grade Equivalency")" in your when, so you cannot also do an IN clause too.
Also when you use the IN clause in the parenthesis you have to put values not table columns.
Maybe you need something like:
case
when MIN("Grade - Current"."Grade Equivalency")=MIN("Grade - Current"."Grade Equivalency") AND MIN("Grade - Current"."Grade Equivalency") IN (one or more values...) then 'y'
else 'n'
end
Second answer...
It's a little more complex, as it uses analytical functions.
Take a look below:
select RECORDKEY, VERSION_YEAR, GRADE,
case
when GRADE_PREV = 0 and GRADE_NEXT >= 0 then 'Stayed the same'
when GRADE_PREV = 0 and GRADE_NEXT > 0 then 'Stayed the same'
when GRADE_PREV > 0 and GRADE_PREV < GRADE then 'increased'
when GRADE_PREV > 0 and GRADE_PREV > GRADE then 'decreased'
else null
end as grade_change
from
(
select RECORDKEY, VERSION_YEAR, GRADE
,LAG(GRADE, 1, 0) over (partition by RECORDKEY order by RECORDKEY, VERSION_YEAR) as GRADE_PREV
,LEAD(GRADE, 1, 0) over (partition by RECORDKEY order by RECORDKEY, VERSION_YEAR) as GRADE_NEXT
from PLCH_GRADES
)
order by 1,2
Third answer...
Here it is, now integrating your "original" query:
select RECORDKEY, CALENDAR_YEAR, HEADCOUNT, GRADE,
case
when GRADE_PREV = 0 and GRADE_NEXT >= 0 then 'Stayed the same'
when GRADE_PREV = 0 and GRADE_NEXT > 0 then 'Stayed the same'
when GRADE_PREV > 0 and GRADE_PREV < GRADE then 'increased'
when GRADE_PREV > 0 and GRADE_PREV > GRADE then 'decreased'
else NULL
end as GRADE_CHANGE
from
(
select RECORDKEY, CALENDAR_YEAR, HEADCOUNT, GRADE
,LAG(GRADE, 1, 0) over (partition by RECORDKEY order by RECORDKEY, VERSION_YEAR) as GRADE_PREV
,LEAD(GRADE, 1, 0) over (partition by RECORDKEY order by RECORDKEY, VERSION_YEAR) as GRADE_NEXT
from
(
select
PEOPLE."Record Key" as RECORDKEY,
CALENDAR.year as CALENDAR_YEAR,
"Grade - Current"."Grade Equivalency" as GRADE,
"Fact - People".HEADCOUNT
from test
where location = 'NI'
and PEOPLE."Status Group" = 'CURRENT'
and PEOPLE."Headcount Marker" in ('Paid', 'Unpaid')
AND Calendar.Year IN ('2009', '2012')
)
)
order by 1,2
I'm trying to get a query to summarize each employees work for the week. For example, John Doe did a total of 12 tickets for the week, 4 of which were Break/Fixes, and 4 were Enhancement, and another 4 were uncategorized.
This is what I have so far:
SELECT (users.first_name || ' ' || users.last_name) AS Name,
COUNT(tickets.id) AS 'Number of Tickets Closed',
COUNT(tickets.category = 'Maintenance') AS 'Maintenance Tickets',
COUNT(tickets.category = 'After Hours') AS 'After Hours Tickets',
COUNT(tickets.category = 'Break Fix') AS 'Break Fix Tickets',
COUNT(tickets.category = 'Enhancement') AS 'Enhancement Tickets',
COUNT(tickets.category = '') AS 'Non Categorized Tickets'
FROM tickets, users
ON tickets.assigned_to=users.id
WHERE (tickets.status = 'closed') AND
(tickets.closed_at >= '2011-07-16 00:00:00') AND
(tickets.closed_at <= '2011-07-22 23:59:59')
GROUP BY Name;
Here is a sample result:
John Doe1 10 10 10 10 10 10
John Doe2 2 2 2 2 2 2
John Doe3 25 24 24 24 24 24
John Doe4 2 2 2 2 2 2
John Doe5 12 10 10 10 10 10
John Doe6 7 7 7 7 7 7
This query doesn't quite work as I expected it to as all of the columns have the same total (The total number of tickets closed, the following columns seems to only contain the categorized ones.) Help?
EDIT
Just wanted to post the functional code:
SELECT (users.first_name || ' ' || users.last_name) AS Name,
COUNT(tickets.id) AS 'Number of Tickets Closed',
COUNT(case tickets.category when 'Maintenance' then 1 else null end) AS 'Maintenance Tickets',
COUNT(case tickets.category when 'After Hours' then 1 else null end) AS 'After Hours Tickets',
COUNT(case tickets.category when 'Break Fix' then 1 else null end) AS 'Break Fix Tickets',
COUNT(case tickets.category when 'Enhancement' then 1 else null end) AS 'Enhancement Tickets',
COUNT(case tickets.category when '' then 1 else null end) AS 'Non Categorized Tickets'
FROM tickets, users
ON tickets.assigned_to=users.id
WHERE (tickets.status = 'closed') AND
(tickets.closed_at >= '2011-07-16') AND
(tickets.closed_at <= '2011-07-22')
GROUP BY Name;
you may want to use COUNT like this
...
COUNT(case tickets.category when 'Maintenance' then 1 else null end),
COUNT(case tickets.category when 'After Hours' then 1 else null end),
...
It seems to me you cannot use an alias in the GROUP BY clause. Don't your users have an ID you could use to differenciate them?
And you must use SUM instead of COUNT if you want to count compared with a condition.
SELECT (users.first_name || ' ' || users.last_name) AS Name,
COUNT(tickets.id) AS 'Number of Tickets Closed',
SUM(tickets.category = 'Maintenance') AS 'Maintenance Tickets',
SUM(tickets.category = 'After Hours') AS 'After Hours Tickets',
SUM(tickets.category = 'Break Fix') AS 'Break Fix Tickets',
SUM(tickets.category = 'Enhancement') AS 'Enhancement Tickets',
SUM(tickets.category = '') AS 'Non Categorized Tickets'
FROM tickets, users
ON tickets.assigned_to=users.id
WHERE (tickets.status = 'closed') AND
(tickets.closed_at >= '2011-07-16 00:00:00') AND
(tickets.closed_at <= '2011-07-22 23:59:59')
GROUP BY Name;