"CASE" statement within "WHERE" clause in SQL Server 2008 - sql

I am working with a query which contains "CASE" statement within "WHERE" clause. But SQL Server 2008 is giving some errors while executing it. Can anyone please help me with the correct query? Here is the query:
SELECT
tl.storenum 'Store #',
co.ccnum 'FuelFirst Card #',
co.dtentered 'Date Entered',
CASE st.reasonid
WHEN 1 THEN 'Active'
WHEN 2 THEN 'Not Active'
WHEN 0 THEN st.ccstatustypename
ELSE 'Unknown'
END 'Status',
CASE st.ccstatustypename
WHEN 'Active' THEN ' '
WHEN 'Not Active' THEN ' '
ELSE st.ccstatustypename
END 'Reason',
UPPER(REPLACE(REPLACE(co.personentered,'RT\\\\',''),'RACETRAC\\\\','')) 'Person Entered',
co.comments 'Comments or Notes'
FROM
comments co
INNER JOIN cards cc ON co.ccnum=cc.ccnum
INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid
INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid
INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd
INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid
LEFT JOIN stores s ON s.StoreNum = tl.StoreNum
WHERE
CASE LEN('TestPerson')
WHEN 0 THEN co.personentered = co.personentered
ELSE co.personentered LIKE '%TestPerson'
END
AND cc.ccnum = CASE LEN('TestFFNum')
WHEN 0 THEN cc.ccnum
ELSE 'TestFFNum'
END
AND CASE LEN('2011-01-09 11:56:29.327')
WHEN 0 THEN co.DTEntered = co.DTEntered
ELSE
CASE LEN('2012-01-09 11:56:29.327')
WHEN 0 THEN co.DTEntered >= '2011-01-09 11:56:29.327'
ELSE co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327'
END
END
AND tl.storenum < 699
ORDER BY tl.StoreNum

First off, the CASE statement must be part of the expression, not the expression itself.
In other words, you can have:
WHERE co.DTEntered = CASE
WHEN LEN('blah') = 0
THEN co.DTEntered
ELSE '2011-01-01'
END
But it won't work the way you have written them eg:
WHERE
CASE LEN('TestPerson')
WHEN 0 THEN co.personentered = co.personentered
ELSE co.personentered LIKE '%TestPerson'
END
You may have better luck using combined OR statements like this:
WHERE (
(LEN('TestPerson') = 0
AND co.personentered = co.personentered
)
OR
(LEN('TestPerson') <> 0
AND co.personentered LIKE '%TestPerson')
)
Although, either way I'm not sure how great of a query plan you'll get. These types of shenanigans in a WHERE clause will often prevent the query optimizer from utilizing indexes.

Try the following:
SELECT * FROM emp_master
WHERE emp_last_name=
CASE emp_first_name
WHEN 'test' THEN 'test'
WHEN 'Mr name' THEN 'name'
END

This should solve your problem for the time being but I must remind you it isn't a good approach :
WHERE
CASE LEN('TestPerson')
WHEN 0 THEN
CASE WHEN co.personentered = co.personentered THEN 1 ELSE 0 END
ELSE
CASE WHEN co.personentered LIKE '%TestPerson' THEN 1 ELSE 0 END
END = 1
AND cc.ccnum = CASE LEN('TestFFNum')
WHEN 0 THEN cc.ccnum
ELSE 'TestFFNum'
END
AND CASE LEN('2011-01-09 11:56:29.327')
WHEN 0 THEN CASE WHEN co.DTEntered = co.DTEntered THEN 1 ELSE 0 END
ELSE
CASE LEN('2012-01-09 11:56:29.327')
WHEN 0 THEN
CASE WHEN co.DTEntered >= '2011-01-09 11:56:29.327' THEN 1 ELSE 0 END
ELSE
CASE WHEN co.DTEntered BETWEEN '2011-01-09 11:56:29.327'
AND '2012-01-09 11:56:29.327'
THEN 1 ELSE 0 END
END
END = 1
AND tl.storenum < 699

I think that the beginning of your query should look like that:
SELECT
tl.storenum [Store #],
co.ccnum [FuelFirst Card #],
co.dtentered [Date Entered],
CASE st.reasonid
WHEN 1 THEN 'Active'
WHEN 2 THEN 'Not Active'
WHEN 0 THEN st.ccstatustypename
ELSE 'Unknown'
END [Status],
CASE st.ccstatustypename
WHEN 'Active' THEN ' '
WHEN 'Not Active' THEN ' '
ELSE st.ccstatustypename
END [Reason],
UPPER(REPLACE(REPLACE(co.personentered,'RT\\\\',''),'RACETRAC\\\\','')) [Person Entered],
co.comments [Comments or Notes]
FROM comments co
INNER JOIN cards cc ON co.ccnum=cc.ccnum
INNER JOIN customerinfo ci ON cc.customerinfoid=ci.customerinfoid
INNER JOIN ccstatustype st ON st.ccstatustypeid=cc.ccstatustypeid
INNER JOIN customerstatus cs ON cs.customerstatuscd=ci.customerstatuscd
INNER JOIN transactionlog tl ON tl.transactionlogid=co.transactionlogid
LEFT JOIN stores s ON s.StoreNum = tl.StoreNum
WHERE
CASE
WHEN (LEN([TestPerson]) = 0 AND co.personentered = co.personentered) OR (LEN([TestPerson]) <> 0 AND co.personentered LIKE '%'+TestPerson) THEN 1
ELSE 0
END = 1
AND
BUT
what is in the tail is completely not understandable

There WHERE part could be written like this:
WHERE
(LEN('TestPerson') <> 0 OR co.personentered = co.personentered) AND
(LEN('TestPerson') = 0 OR co.personentered LIKE '%TestPerson') AND
(cc.ccnum = CASE LEN('TestFFNum')
WHEN 0 THEN cc.ccnum
ELSE 'TestFFNum'
END ) AND
(LEN('2011-01-09 11:56:29.327') <> 0 OR co.DTEntered = co.DTEntered ) AND
((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') <> 0) OR co.DTEntered >= '2011-01-09 11:56:29.327' ) AND
((LEN('2011-01-09 11:56:29.327') = 0 AND LEN('2012-01-09 11:56:29.327') = 0) OR co.DTEntered BETWEEN '2011-01-09 11:56:29.327' AND '2012-01-09 11:56:29.327' ) AND
tl.storenum < 699

select
d.DISTNAME,e.BLKNAME,a.childid,a.studyingclass
from Tbl_AdmissionRegister a
inner join District_master b on a.Schooid=b.Schooid
where
case when len('3601')=4 then c.distcd
when len('3601')=6 then c.blkcd
when len('3601')=11 then c.schcd end = '3601'

Thanks for this question, actually I am looking for something else which is in below query. this may helps someone.
SELECT DISTINCT CASE WHEN OPPORTUNITY='' THEN '(BLANK)' ELSE OPPORTUNITY END
AS OPP,LEN(OPPORTUNITY) FROM [DBO].[TBL]
above query is to fill in dropdown which blank values shows as "(blank)". Also if we pass this value into sql where clause to get blank values with other values I don't know how to handle that. And finally came up with below solution this may helps to somebody.
here it is ,
DECLARE #OPP TABLE (OPP VARCHAR(100))
INSERT INTO #OPP VALUES('(BLANK)'),('UNFUNDED'),('FUNDED/NOT COMMITTED')
SELECT DISTINCT [OPPORTUNITY]
FROM [DBO].[TBL] WHERE ( CASE WHEN OPPORTUNITY ='' THEN '(BLANK)' ELSE OPPORTUNITY END IN (SELECT OPP FROM #OPP))
ORDER BY 1

You could also try like below eg. to show only Outbound Shipments
SELECT shp_awb_no,shpr_ctry_cd, recvr_ctry_cd,
CASE WHEN shpr_ctry_cd = record_ctry_cd
THEN "O"
ELSE "I"
END AS route
FROM shipment_details
WHERE record_ctry_cd = "JP"
AND "O" = CASE WHEN shpr_ctry_cd = record_ctry_cd
THEN "O"
ELSE "I"
END

CASE LEN('TestPerson')
WHEN 0 THEN co.personentered = co.personentered ELSE co.personentered LIKE '%TestPerson'
Try the following:
... and (
(LEN('TestPerson') = 0 and co.personentered = co.personentered) or
(LEN('TestPerson') <> 0 and co.personentered LIKE '%TestPerson') ) and ...

here is my solution
AND CLI.PE_NOM Like '%' + ISNULL(#NomClient, CLI.PE_NOM) + '%'
Regads
Davy

This works
declare #v int=A
select * from Table_Name where XYZ=202
and
dbkey=(case #v when A then 'Some Value 1'
else 'Some Value 2'
end)

I'm using somtehing like that to filter users according to needle as string and a dropdown in the UI
where
u.username like '%' + isnull(#needle, '') + '%'
and 1 =
(
case
when #status = 0 then 1 -- All in uu
when #status = u.statusid then 1 -- Special status
else 0 -- otherwise reject
end
)

select TUM1.userid,TUM1.first_name + ' ' +TUM1.last_name as NAME,tum1.Business_Title,TUM1.manager_id,tum2.First_Name + ' ' + tum2.Last_Name as [MANAGER NAME],TUM1.project,TUM1.project_code,TUM1.rcc_code,TUM1.department,TCM.Company_Name,
case
when tum1.Gender_ID=1 then 'male'
else 'female'
end 'GENDER'
,tum1.Band as BAND,
case when tum1.Inactive=0 then 'STILL IN COMPANY'
else 'LEFT COMPANY'
end 'ACTIVE/INACTIVE'
from tbl_user_master TUM1
join tbl_Company_Master TCM on TCM.Company_Code=TUM1.Company_Code
join tbl_User_Master TUM2 on TUM1.Manager_ID=TUM2.UserID
where tum1.UserID in ('54545414')

SELECT * from TABLE
WHERE 1 = CASE when TABLE.col = 100 then 1
when TABLE.col = 200 then 2 else 3 END
and TABLE.col2 = 'myname';
Use in this way.

Related

mismatched input '(' expecting <EOF>(line 3, pos 28)

My code looks like this, I do not know why it raising an error, the error is in line 3 after case when, Can anyone help on this? thanks
SELECT
CASE
WHEN
(
CASE
WHEN
(
ltrim(rtrim(status)) = 'CANCELLED'
AND ltrim(rtrim(COALESCE(iscancelledwithte, - ))) = '0'
)
THEN
CASE
WHEN
(
mincancellationdate IS NULL
)
THEN
CASE
WHEN
(
lastupdatedts IS NULL
)
THEN
'9999-12-31'
ELSE
lastupdatedts
END
ELSE
mincancellationdate
END
ELSE
CASE
WHEN
(
approvedforbillingts IS NULL
)
THEN
'9999-12-31'
ELSE
approvedforbillingts
END
END
)
= '9999-12-31'
THEN
status
ELSE
'Closed'
END
AS casestatusname
FROM
tblrequesttemp AS tblrequests
I've paste your sql request into SQL Syntax Checker (https://www.eversql.com/sql-syntax-check-validator/), and it return an error in your coalesce function. I believe you forget the quotes around the tiret character.
There is the fixed SQL Request:
SELECT
CASE
WHEN (
CASE
WHEN (Ltrim(Rtrim(status)) = 'CANCELLED' AND ltrim(rtrim(coalesce(iscancelledwithte, '-'))) = '0') THEN
CASE
WHEN (mincancellationdate IS NULL) THEN
CASE
WHEN (lastupdatedts IS NULL) THEN '9999-12-31'
ELSE lastupdatedts
end
ELSE mincancellationdate
end
ELSE
CASE
WHEN (approvedforbillingts IS NULL) THEN '9999-12-31'
ELSE approvedforbillingts
end
end) = '9999-12-31' THEN status
ELSE 'Closed'
end
AS casestatusname
FROM tblrequesttemp AS tblrequests

Why wont my temp table populate data but the select statement inside of it will?

I have been stuck on a problem that has been a huge blocker for me. I cant seem to wrap my head around this issue and I was hoping someone can help provide me with some guidance.
So my problem is when I create my temp table, and I do
select * from all_subs
I get a blank table. However, when I test to run the select statement that comprises the temp table I get results...
My query looks like this
drop table if exists all_subs;
select sdb.id as subscription_id,
sdb.created_at,
sdb.user_id as user_id,
sdb.is_gift as is_gift,
case when pl.sku like '%auto-cancel%' then 1 else 0 end as is_auto_cancel,
sdb.current_period_ends_at as current_period_ends_at,
sdb.expires_at as expires_at,
sdb.current_period_started_at as current_period_started_at,
case when sdb.expires_at is null then 0 else 1 end as expiring,
case when pl.sku ilike '%mobi1' then 1
when pl.sku ilike '%mobi6' then 6
when pl.sku ilike '%mobi12' then 12
else pl.duration end as duration,
sdb.dog_name as dog_name,
sdb.dog_birthday as dog_birthday,
pl.sku as sku,
cast(round(100.0 * pl.price, 0) as int) as price,
cast(round(100.0 * pl.price / pl.duration, 0) as int) as mrr,
case
when sdb.expires_at is null and getdate() between sdb.current_period_started_at and sdb.current_period_ends_at then 'active'
when sdb.expires_at > getdate() then 'canceled'
when sdb.expires_at <= getdate() or (sdb.expires_at is null and sdb.current_period_ends_at < date_add('day',-30,getdate())) then 'expired'
else 'unknown'
end as subscription_state,
coalesce(can.no_new_products, false) as no_new_products,
coalesce(can.dog_did_not_like, false) as dog_did_not_like,
coalesce(can.not_enough_value, false) as not_enough_value,
coalesce(can.dog_died, false) as dog_died,
coalesce(can.cant_afford, false) as cant_afford,
coalesce(can.offer_accepted, false) as offer_accepted,
coalesce(can.too_big_too_small, false) as too_big_too_small,
coalesce(can.allergies, false) as allergies,
coalesce(can.too_much_treats, false) as too_much_treats,
coalesce(can.too_few_toys, false) as too_few_toys,
coalesce(can.toy_durability, false) as toy_durability,
coalesce(can.new_address, false) as new_address,
coalesce(can.something_different, false) as something_different,
case when ais.subscription_id is not null then 1 else 0 end add_item,
case when eets.subscription_id is not null then 1 else 0 end ever_extra_toy,
case when sdb.allergies = '{""}' then 0
when sdb.allergies is null then 0
else 1 end as is_allergy,
min(s.shipped_at) first_box_shipped_at,
count(distinct case when s.shipped_at is not null then o.id end) shipped_orders,
cast((case when (sdb.expires_at <= getdate() or (sdb.expires_at is null and sdb.current_period_ends_at < date_add('day',-30,getdate())))
and count(distinct case when s.shipped_at is not null then o.id end) = 0 then 1 else 0 end) as boolean) is_killed
into temp all_subs
from subscriptions as sdb
left join subscription_cancellation_summary as can on can.subscription_id = sdb.id
left join plans as pl on pl.id = sdb.current_plan_id
left join add_item_subs ais on ais.subscription_id = sdb.id
left join ever_extra_toy_subs eets on eets.subscription_id = sdb.id
left join orders o on o.orderable_type = 'Subscription' and o.orderable_id = sdb.id
left join orders_shipments os on os.order_id = o.id
left join shipments s on s.id = os.shipment_id
left join common.subs_dim sd on sd.subscription_id = sdb.id
where
-- Only valid subscriptions
sd.is_killed = false
group by sdb.id,
sdb.created_at,
sdb.user_id,
sdb.is_gift,
case when pl.sku like '%auto-cancel%' then 1 else 0 end,
sdb.current_period_ends_at,
sdb.expires_at,
sdb.current_period_started_at,
case when sdb.expires_at is null then 0 else 1 end,
case when pl.sku ilike '%mobi1' then 1
when pl.sku ilike '%mobi6' then 6
when pl.sku ilike '%mobi12' then 12
else pl.duration end,
sdb.dog_name,
sdb.dog_birthday,
pl.sku,
cast(round(100.0 * pl.price, 0) as int),
cast(round(100.0 * pl.price / pl.duration, 0) as int),
case
when sdb.expires_at is null and getdate() between sdb.current_period_started_at and sdb.current_period_ends_at then 'active'
when sdb.expires_at > getdate() then 'canceled'
when sdb.expires_at <= getdate() or (sdb.expires_at is null and sdb.current_period_ends_at < date_add('day',-30,getdate())) then 'expired'
else 'unknown'
end,
coalesce(can.no_new_products, false),
coalesce(can.dog_did_not_like, false),
coalesce(can.not_enough_value, false),
coalesce(can.dog_died, false),
coalesce(can.cant_afford, false),
coalesce(can.offer_accepted, false),
coalesce(can.too_big_too_small, false),
coalesce(can.allergies, false),
coalesce(can.too_much_treats, false),
coalesce(can.too_few_toys, false),
coalesce(can.toy_durability, false),
coalesce(can.new_address, false),
coalesce(can.something_different, false),
case when ais.subscription_id is not null then 1 else 0 end,
case when eets.subscription_id is not null then 1 else 0 end,
case when sdb.allergies = '{""}' then 0
when sdb.allergies is null then 0
else 1 end;
Has anybody come across this issue? Please help!
Thank you very much in advance
Try changing the
into temp all_subs
to
INTO TEMP TABLE all_subs

Multiple case statement not working as expected in Postgres

This is the query:
SELECT DISTINCT
completed_phases,
CAST(completed_phases::bit(8) AS VARCHAR),
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=1 THEN 'FT' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=2 THEN 'ED' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=3 THEN 'MC' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=4 THEN 'HC' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=5 THEN 'UV' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=6 THEN 'TT' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=7 THEN 'RX' ELSE '' END ||
CASE WHEN STRPOS(CAST(completed_phases::bit(8) AS VARCHAR),'1')=8 THEN 'PI' ELSE '' END
FROM rx_sales_order
If completed_phase is 129, my output for final column should be FTPI. But it is only showing FT. Only the first case statement seems to work, even if all of them are distinct.
STRPOS() will always return the first occurance of the searched string. So all calls to strpos() will return 1 for the input value 129.
You can use substring() instead:
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),1,1)='1' THEN 'FT' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),2,1)='1' THEN 'ED' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),3,1)='1' THEN 'MC' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),4,1)='1' THEN 'HC' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),5,1)='1' THEN 'UV' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),6,1)='1' THEN 'TT' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),7,1)='1' THEN 'RX' ELSE '' END ||
CASE WHEN substring(CAST(completed_phases::bit(8) AS VARCHAR),8,1)='1' THEN 'PI' ELSE '' END
Another option would be to use get_bit() to test each bit individually:
case when get_bit(completed_phases::bit(8), 0) = 1 then 'FT' else '' END||
case when get_bit(completed_phases::bit(8), 1) = 1 then 'ED' else '' END||
case when get_bit(completed_phases::bit(8), 2) = 1 then 'MC' else '' END||
case when get_bit(completed_phases::bit(8), 3) = 1 then 'HC' else '' END||
case when get_bit(completed_phases::bit(8), 4) = 1 then 'UV' else '' END||
case when get_bit(completed_phases::bit(8), 5) = 1 then 'TT' else '' END||
case when get_bit(completed_phases::bit(8), 6) = 1 then 'RX' else '' END||
case when get_bit(completed_phases::bit(8), 7) = 1 then 'PI' else '' END
A more flexible way of doing that is to turn the bits into rows and use an array as a lookup. Something like:
with lookup (codes) as (
values (array['FT','ED','MC','HC','UV','TT','RX','PI'])
)
SELECT completed_phases,
completed_phases::bit(8),
x.code
FROM rx_sales_order
join lateral (
select string_agg(codes[i],'') as code
from lookup, unnest(string_to_array(completed_phases::bit(8)::text, null)) with ordinality as t(b,i)
where b = '1'
) as x on true
The part regexp_split_to_table(completed_phases::bit(8)::text, '') with ordinality as t(b,i) will return the following for the value 129:
b | i
--+--
1 | 1
0 | 2
0 | 3
0 | 4
0 | 5
0 | 6
0 | 7
1 | 8
code[i] the uses the index to lookup the matching code and string_agg() then puts all selected codes together again into a single string. The condition where b = '1' only selects the bits that are set.
That solution will be substantially slower than the hardcoded case expression (because it increases the number of rows, just to reduce them again) - but it is more flexible and easier to maintain.
If you need that a lot, the best option would be to put the case expression into a function and use the function in your queries.
create or replace function get_codes(p_phases integer)
returns text
as
$$
select
case when get_bit(p_phases::bit(8), 0) = 1 then 'FT' else '' END||
case when get_bit(p_phases::bit(8), 1) = 1 then 'ED' else '' END||
case when get_bit(p_phases::bit(8), 2) = 1 then 'MC' else '' END||
case when get_bit(p_phases::bit(8), 3) = 1 then 'HC' else '' END||
case when get_bit(p_phases::bit(8), 4) = 1 then 'UV' else '' END||
case when get_bit(p_phases::bit(8), 5) = 1 then 'TT' else '' END||
case when get_bit(p_phases::bit(8), 6) = 1 then 'RX' else '' END||
case when get_bit(p_phases::bit(8), 7) = 1 then 'PI' else '' END
$$
language sql;
Then use:
SELECT DISTINCT
completed_phases,
get_codes(completed_phases) as codes
FROM rx_sales_order
As pointed out in the answer by a_horse_with_no_name, strpos will return the first occurrence of the searched string. At any rate, it's better to use get_bit instead of casting to VARCHAR to check if a bit is set. Also, instead of ||, you can use concat, which will handle nulls as blank strings. Your query could then be rewritten to:
SELECT DISTINCT
completed_phases,
CAST(completed_phases::bit(8) AS VARCHAR),
concat(CASE get_bit(completed_phases::bit(8), 0) WHEN 1 THEN 'FT' END,
CASE get_bit(completed_phases::bit(8), 1) WHEN 1 THEN 'ED' END,
CASE get_bit(completed_phases::bit(8), 2) WHEN 1 THEN 'MC' END,
CASE get_bit(completed_phases::bit(8), 3) WHEN 1 THEN 'HC' END,
CASE get_bit(completed_phases::bit(8), 4) WHEN 1 THEN 'UV' END,
CASE get_bit(completed_phases::bit(8), 5) WHEN 1 THEN 'TT' END,
CASE get_bit(completed_phases::bit(8), 6) WHEN 1 THEN 'RX' END,
CASE get_bit(completed_phases::bit(8), 7) WHEN 1 THEN 'PI' END)
FROM rx_sales_order;
On a side note, if you have the option to do so, I would recommend changing your database schema to store the phases as individual boolean columns instead of using a bit map. See Any disadvantages to bit flags in database columns? for a good discussion of why.

How to count non-null/non-blank values in SQL

I have data like the following:
And what I want is to count the PONo, PartNo, and TrinityID fields with a value in them, and output data like this:
How can I do this counting in SQL?
select
Job_number, Item_code,
case when RTRIM(PONo) = '' or PONo is null then 0 else 1 end +
case when RTRIM(PartNo) = '' or PartNo is null then 0 else 1 end +
case when RTRIM(TrinityID) = '' or TrinityID is null then 0 else 1 end
as [Count]
from YourTable
Try this:
select Job_Number = t.Job_Number ,
Item_Code = t.Item_Code ,
"Count" = sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
)
from dbo.my_table t
group by t.Job_Number , t.Item_Code
If you want to exclude data where all the tested fields are null or empty, add a having clause:
having sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
) > 0
Easy!

Concatenating multiple CASE statements into one alias

After some previous help on how to approach a problem I am having with some legacy code, it seems like the best approach for my issue is to concatenate case statements to return a value I can parse out in PHP.
I am trying to do something like this, but it is returning many rows, and eventually getting this error:
Maximum stored procedure, function, trigger, or view nesting level
exceeded (limit 32).
SELECT org.org_id,
org.org_name_1,
Datename(YEAR, member.enroll_date) AS enroll_year,
Max(CASE
WHEN board.member_from IS NULL THEN 0
ELSE 1
END) AS board_member,
CASE
WHEN ( org.delete_reason = 'OUT'
AND org.org_delete_flag = 'Y'
AND org.org_status_flag = 'C' ) THEN 'out_of_business|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues > 0 ) THEN 'insurance_member|'
ELSE ''
END + CASE
WHEN ( stat.carrier = 'BS'
AND stat.status_id IS NOT NULL
AND stat.termination_date IS NULL
AND stat.flat_dues = 0
AND member.status_flag IN( 'C', 'P' ) ) THEN 'insurance_product|'
ELSE ''
END + CASE
WHEN ( member.enroll_date IS NOT NULL
AND member.status_flag NOT IN( 'C', 'P' ) ) THEN 'member_since|'
ELSE ''
END + CASE
WHEN ( org.org_relationship_parent = 'Y'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 'subsidiary_member|'
ELSE ''
END + CASE
WHEN ( org.org_misc_data_9 = 'PAC' ) THEN 'pac|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'PART' ) THEN 'partner_member|'
ELSE ''
END + CASE
WHEN ( org.dues_category = 'FREE'
AND org.org_status_flag = 'P' ) THEN 'associate_member|'
ELSE ''
END
--ELSE 'non_member'
--END
AS org_status,
60 AS expires_in,
CASE
WHEN stat.dues_type = 'M' THEN
CASE
WHEN ( stat.termination_date IS NULL ) THEN ( stat.flat_dues )
ELSE 0
END
ELSE
CASE
WHEN ( member.payments = 0 ) THEN member.dues_billed_annual
ELSE member.payments
END
END AS dues_level,
CASE
WHEN ( org.affiliate_code = 'PCCE'
AND org.dues_category = 'MBR'
AND org.org_status_flag = 'R' ) THEN 1
ELSE 0
END AS pcce_membr,
-- '$'+CONVERT(VARCHAR,#dues) AS dues_level,
Ltrim(#product_level) AS product_level,
Ltrim(#involve_level) AS involvement_level
FROM organiz AS org
LEFT JOIN affilbil AS member
ON member.status_id = org.org_id
AND member.dues_category = 'MBR'
LEFT JOIN individu AS ind
ON ind.org_id = org.org_id
LEFT JOIN commembr AS board
ON board.status_id = ind.ind_id
AND board.committee_code = '5'
AND board.member_to IS NULL
LEFT JOIN statinsmorn AS stat
ON stat.status_id = org.org_id
AND stat.carrier = 'BS'
AND stat.planz = 'PCI'
WHERE org.org_id = #org_id
GROUP BY org.org_id,
org.org_name_1,
member.enroll_date,
org.delete_reason,
org.org_status_flag,
org.org_delete_flag,
stat.status_id,
stat.flat_dues,
stat.dues_type,
stat.termination_date,
org.org_misc_data_9,
org_relationship_parent,
org.dues_category,
member.status_flag,
member.dues_billed_annual,
member.payments,
stat.carrier,
org.Affiliate_Code
Well, this is embarrassing.
When I was making my changes to the stored procedure, I had inadvertently placed a call to the same procedure at the bottom. So I was recursively calling the same procedure over and over again. DOH.