Case statement in group by clause - sql

My current query works however, I can not seem to get another column name to explain what the data is.
Query:
SELECT
SUM(item_subtotal) AS rev
FROM
[ADAS].[dbo].[ADAS_ORDERS] x
LEFT JOIN
ADAS.dbo.ADAS_SUBSCRIPTIONS y ON x.SUBSCRIPTION_KEY = y.SUBSCRIPTION_KEY
AND x.CUSTOMER_ID = y.customer_id
AND x.ITEM_NUM = y.ITEM_NUM
WHERE
x.ORDER_DATE BETWEEN '10-01-2021' AND '10-31-2021'
AND x.ORDER_STATUS = 'success'
AND x.IMPULSE_FLG = 'n'
GROUP BY
CASE
WHEN y.OFFER_ID IS NULL
THEN 'Null'
WHEN y.OFFER_ID IN ('1882', '1883', '4554', '4576')
THEN 'in-store'
ELSE 'web'
END
ORDER BY
1
Result
How do I get the other column to have a name?

You may try including the case expression in the group by in your select/projection also eg
SELECT
sum(item_subtotal)as rev,
case when y.OFFER_ID is null then 'Null'
when y.OFFER_ID in('1882','1883','4554','4576') then 'in-store' else 'web' end as offer_location
FROM [ADAS].[dbo].[ADAS_ORDERS] x
left join ADAS.dbo.ADAS_SUBSCRIPTIONS y on x.SUBSCRIPTION_KEY = y.SUBSCRIPTION_KEY
and x.CUSTOMER_ID = y.customer_id
and x.ITEM_NUM = y.ITEM_NUM
where x.ORDER_DATE between '10-01-2021' and '10-31-2021'
and x.ORDER_STATUS = 'success'
and x.IMPULSE_FLG = 'n'
group by case when y.OFFER_ID is null then 'Null'
when y.OFFER_ID in('1882','1883','4554','4576') then 'in-store' else 'web' end
order by 1

Related

Using a CASE WHEN statement and an IN (SELECT...FROM) subquery

I'm trying to create a temp table and build out different CASE WHEN logic for two different medications. In short I have two columns of interest for these CASE WHEN statements; procedure_code and ndc_code. There are only 3 procedure codes that I need, but there are about 20 different ndc codes. I created a temp.ndcdrug1 temp table with these ndc codes for medication1 and temp.ndcdrug2 for the ndc codes for medication2 instead of listing out each ndc code individually. My query looks like this:
CREATE TABLE temp.flags AS
SELECT DISTINCT a.userid,
CASE WHEN (procedure_code = 'J7170' OR ndc_code in (select ndc_code from temp.ndcdrug1)) THEN 'Y' ELSE 'N' END AS Drug1,
CASE WHEN (procedure_code = 'J7205' OR procedure_code = 'C9136' OR ndc_code in (select ndc_code from temp.ndcdrug2)) THEN 'Y' ELSE 'N' END AS Drug2,
CASE WHEN (procedure_code = 'J7170' AND procedure_code = 'J7205') THEN 'Y' ELSE 'N' END AS Both
FROM table1 a
LEFT JOIN table2 b
ON a.userid = b.userid
WHERE...
AND...
When I run this, it returns: org.apache.spark.sql.AnalysisException: IN/EXISTS predicate sub-queries can only be used in a Filter.
I could list these ndc_code values out individually, but there are a lot of them so wanted a more efficient way of going about this. Is there a way to use a sub select query like this when writing out CASE WHEN's?
Query.
CREATE TABLE temp.flags AS
SELECT DISTINCT a.userid,
CASE WHEN (
procedure_code = 'J7170' OR
(select min('1') from temp.ndcdrug1 m where m.ndc_code = a.ndc_code) = '1'
) THEN 'Y' ELSE 'N' END AS Drug1,
CASE WHEN (
procedure_code = 'J7205' OR
procedure_code = 'C9136' OR
(select min('1') from temp.ndcdrug2 m where m.ndc_code = a.ndc_code) = '1'
) THEN 'Y' ELSE 'N' END AS Drug2,
CASE WHEN (procedure_code = 'J7170' AND procedure_code = 'J7205')
THEN 'Y' ELSE 'N' END AS Both
FROM table1 a
LEFT JOIN table2 b
ON a.userid = b.userid
WHERE...
AND...

Defaulting result in case expression using count

I currently am casing off of a big select statement. I am trying to work through the case portion. I currently have the case set up where it will take the name 'Brad' where units are 'inches'.
If I get rid of the units, it will show more than one result. Is there a way to default in the case statement where the case returns more than one result for 'brad'? Where if there is only 1 result, it will show that result, otherwise if there is more than 1 result, use units = 'inches'?
Here is the working case statement:
And case when R.name = 'Brad' and R.units ='Inches' then 0 else 1 End = 1
Here is a non working semi-psedu version of what I'd like to do:
And case when Count(R.name ='Brad') > 1 then (R.name = 'Brad' and R.units = 'Inches') else (R.name = 'Brad' ) End
Regardless it should return 1 result, default to inches if it returns more than 1 for the name 'Brad'
Here is the portion of the statement how it is joined.
select r.name, r.units, r.blah
From items I
Inner Join Results.R (NoLock)
ON I.Code = R.Code
WHERE r.status IN ('Y','N')
And case when R.name = 'Brad' and R.units ='Inches' then 0 else 1 End = 1

Can i use case expressions on both sides of the where clause?

Like this
SELECT *
FROM UsersMedicalSurgicalHistory UMSH INNER JOIN CCDTransaction CT on
UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(CASE
WHEN LEN(UMSH.DateOfProcedure)<=4 THEN UMSH.DateOfProcedure
WHEN LEN(UMSH.DateOfProcedure)=0 THEN UMSH.DateOfProcedure
END
=
CASE WHEN #CodeFilter3 IS not null THEN #CodeFilter3
ELSE UMSH.DateOfProcedure end)
OR
(CASE
WHEN LEN(UMSH.DateOfProcedure)>4 THEN
CONVERT(datetime,UMSH.DateOfProcedure,101)
ELSE GETDATE()
END
=
CASE WHEN #CodeFilter2 IS not null THEN #CodeFilter2
ELSE GETDATE()
END)
)
So the question is like CASE expression can be used on both side of WHERE clause
As per your query is written above...
CASES can be minimized to nested conditions as,
SELECT * FROM UsersMedicalSurgicalHistory UMSH
INNER JOIN CCDTransaction CT on UMSH.SurgicalHistoryId = CT.RowId
WHERE (
(UMSH.DateOfProcedure = #CodeFilter3 and #CodeFilter3 IS not null)
OR
#CodeFilter3 IS null
)
OR
(
(
(LEN(UMSH.DateOfProcedure)>4 AND CONVERT(datetime,UMSH.DateOfProcedure,101)=#CodeFilter2)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND GETDATE() =#CodeFilter2)
AND #CodeFilter2 IS NOT NULL
)
OR
(LEN(UMSH.DateOfProcedure)<=4 AND #CodeFilter2 IS null)
)
Try this query... hope it gives desired output :)

get text from int value in select case of sql query

I need convert int value in a select for string value for human Reading.
I try two forms but any works
select id, case Preparacion when 1 then 'Yes' when 0 then 'No' else preparacion end as Preparación
from pinchos
inner join Laboratorios on Laboratorios.CodKais = Pinchos.codKais
where entradaproduccion = '20140905'
And convert Preparacion to varchar()
select id, case convert(varchar(1),Preparacion) when '1' then 'Yes' when '0' then 'No' else preparacion end as Preparacion
from pinchos
inner join Laboratorios on Laboratorios.CodKais = Pinchos.codKais
where entradaproduccion = '20140905'
how I can show string value?
I only have read permisions in database and dont have Preparación table
Compare as INT and cast when required.
Try this:
(untested code)
select id,
case Preparacion
when 1 then 'Yes'
when 0 then 'No'
else CAST(preparacion as VARCHAR(255))
end as Preparacion
from pinchos
inner join Laboratorios on Laboratorios.CodKais = Pinchos.codKais
where entradaproduccion = '20140905'
You have forgottone an else there
select id, case Preparacion
when 1 then 'Yes'
else
when 0 then 'No' else preparacion end
end as Preparación
from pinchos
inner join Laboratorios on Laboratorios.CodKais = Pinchos.codKais
where entradaproduccion = '20140905'

using CASE WHEN in SQL Statement

I have to display information by comparing data in two ID columns, one column has 'ALL' and numbers as ID's while the other has only numbers in it as ID's. My problem is, I cannot compare character and number columns with a number column. So I am using CASE WHEN.
If the value is 'ALL' then display 'ALL' in the output, else display name for the matching records.
Here is the code:
CASE
WHEN secorg.org_id = 'ALL' THEN 'ALL'
WHEN secorg.org_id = progmap.org_id THEN secorg.org_name
END AS org_name,
the condition is this: 'secorg.org_id = progmap.org_id' which is based on the id and I have to display secorg.org_name if the id's are same.
Here is the entire query:
SELECT distinct program_id,
prog_name,
case
when Eitc_Active_Switch = '1' then 'ON'
when Eitc_Active_Switch = '0'then 'OFF'
End as Prog_Status,
progmap.client_id,
case
when secorg.org_id = 'ALL' then 'ALL'
--when secorg.org_id = progmap.org_id then secorg.org_name
else secorg.org_name
end as org_name,
case
when prog.has_post_calc_screen = 'True' then 'True'
Else 'False'
End as Referal_ID,
case
when progmap.program_ID IN ( 'AMC1931', 'AMCABD', 'AMCMNMI',
'AMC' )
And sec.calwinexists_ind = '1' then 'Yes'
when progmap.program_ID IN ( 'AMC1931', 'AMCABD', 'AMCMNMI',
'AMC' )
And sec.calwinexists_ind = '0'then 'No'
when progmap.program_ID NOT IN (
'AMC1931', 'AMCABD', 'AMCMNMI', 'AMC' ) then
'N/A'
End as calwin_interface,
sec.Client_name
FROM ref_programs prog (nolock)
LEFT OUTER JOIN ref_county_program_map progmap (nolock)
ON progmap.program_id = prog.prog_id
AND progmap.CLIENT_ID = prog.CLIENT_ID
INNER join sec_clients sec (nolock)
on sec.client_id = progmap.Client_id
Inner join sec_organization secorg (nolock)
on secorg.org_id = progmap.org_id
Why not cast the number columns to varchar columns?
If you're using SQL SERVER you can do that like so:
CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id)
You'll have to do an outer join for instances when the column that is both 'ALL' and numbers is 'All' as it won't be able to inner join to the other table.
For the quick fix based on your code above you can just change the second WHEN clause to look like so (again assuming you're using MS SQL SERVER):
WHEN CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id) THEN secorg.org_name
Try this as your query:
SELECT DISTINCT
program_id,
prog_name,
CASE Eitc_Active_Switch
WHEN '1' THEN 'ON'
ELSE 'OFF'
END AS Prog_Status,
progmap.client_id,
ISNULL(secorg.org_name,'ALL') AS org_name,
CASE prog.has_post_calc_screen
WHEN 'True' THEN 'True'
ELSE 'False'
END AS Referal_ID,
CASE WHEN progmap.program_ID IN ('AMC1931','AMCABD','AMCMNMI','AMC') AND sec.calwinexists_ind = '1' THEN
'Yes'
WHEN progmap.program_ID IN ('AMC1931','AMCABD','AMCMNMI','AMC') AND sec.calwinexists_ind = '0' THEN
'No'
WHEN progmap.program_ID NOT IN ('AMC1931','AMCABD','AMCMNMI','AMC') THEN
'N/A'
END AS calwin_interface,
sec.Client_name
FROM
ref_programs prog (nolock)
LEFT OUTER JOIN ref_county_program_map progmap (nolock) ON progmap.program_id = prog.prog_id AND progmap.CLIENT_ID = prog.CLIENT_ID
INNER JOIN sec_clients sec (nolock) ON sec.client_id = progmap.Client_id
LEFT OUTER JOIN sec_organization secorg (nolock) ON CONVERT(VARCHAR,secorg.org_id) = CONVERT(VARCHAR,progmap.org_id)
The case statement is fine its the field alias thats bad it shoud be
END As org_name
A multipart alias like secorg.org_name won't work