Getting error with CASE expression using WHERE clause - sql-server-2008

declare #SP nvarchar(3)
SELECT HDR.SOPNUMBE, HDR.docdate, HDR.pymtrmid,
RTRIM(HDR.ShipToName) +
CASE WHEN HDR.ADDRESS1 <> '' THEN char(10) + RTRIM(HDR.ADDRESS1) ELSE '' END
FROM vSOPHdr HDR
WHERE HDR.SOPTYPE = 2 AND
(CASE WHEN HDR.SLPRSNID <> 'All'
then HDR.SLPRSNID in (''+#SP+'')
else HDR.SLPRSNID between '0' and 'ZZZZZZZZZZZZZZZ'
end)
I am trying to run the above query in sql query analyzer but getting 'syntax' errors in the CASE expression (near IN, ELSE). What could be wrong?
All I want to do is when sales-personID is selected as ALL in the report parameter I would like to process all sales person else only the selected sales person ID.
Just a background about what I am doing,
I have a similar query to the above query (without the CASE condition) within a dataset for a SSRS report.
Note that #SP is a report parameter.

CASE is an expression that returns a single value. It cannot be used for control-of-flow logic, like in other languages such as VB. Try:
WHERE HDR.SOPTYPE = 2 AND
((HDR.SLPRSNID <> 'All' AND HDR.SLPRSNID = #SP)
OR
(HDR.SLPRSNID = 'All'))
Though it seems like maybe you need instead, which would make more logical sense if the user is potentially passing 'All' into the parameter:
WHERE HDR.SOPTYPE = 2 AND
((#SP <> 'All' AND HDR.SLPRSNID = #SP)
OR
(#SP = 'All'))

you can just use an OR clause
WHERE HDR.SOPTYPE = 2 AND
((HDR.SLPRSNID <> 'All' AND HDR.SLPRSNID IN (''+#SP+''))
OR
(HDR.SLPRSNID = 'All' AND HDR.SLPRSNID BETWEEN '0' and 'ZZZZZZZZZZ'))
Not sure if the BETWEEN '0' and 'ZZZZZZZZZZZ' means "IN everything". If yes, you can just remove it now.
If you absolutely wanna use a CASE WHEN, you can do it this way :
WHERE HDR.SOPTYPE =2
AND (CASE WHEN HDR.SLPRSNID <>'All' AND HRD.SLPRSNDID IN (''+#SP+'')) THEN 1
WHEN HDR.SLPRSNID = 'All' AND HDR.SLPRSNID BETWEEN '0' and 'ZZZZZZZZZZ' THEN 1
ELSE 0
END) = 1

Related

How to use placeholder in sql to another column in select

i want to make a report and i already calculate it in one column then i want to use the result to another column, something like this
select addtime (timediff(a,b), c) as 'total_lead', case when
total_lead <= then 'yes' else 'no' end as 'check data' from d
so i want to use the result and use it in another column
anyone can help?
You have to either repeat the expression:
select
addtime(timediff(a,b), c) as 'total_lead',
case when addtime(timediff(a,b), c) <= ? then 'yes' else 'no' end as 'check data'
or use a subquery, which may change the performance:
select
total_lead,
case when total_lead <= ? then 'yes' else 'no' end as 'check data'
from (
select
addtime(timediff(a,b), c) as 'total_lead'
from d
) d_with_total_lead

CASE Statement MYSQL with Condition

I got 2 CASE statements: First CASE statement is as follows:
Case When ((cust_shipmentdate_awb Is Null OR cust_shipmentdate_awb = '')
AND (comp_shipdate_awb IS NULL OR comp_shipdate_awb = '')) Then 'Pending'
ELSE 'Shipped' End AS shipment_status
The Second CASE statement is as follows:
Case When apbg_bal_pay_amt ='0' Then 'Received'
Else 'Pending' End AS payment_status
Iam looking to write one more CASE statement named OVERALL_Status. That is basically a combination of both this CASES (shipment_status and payment_status), which means if Shipment status is 'Shipped' AND Payment_Status is 'Received' then Overall_status is 'Completed' else 'Not Completed'. Can anyone please help me on this. I am really struck here. I tried the combination of both the CASES, but not working:
Case When (cust_shipmentdate_awb Is Null OR cust_shipmentdate_awb = '') AND
(comp_shipdate_awb IS NULL OR comp_shipdate_awb = '') AND (apbg_bal_pay_amt != '0') Then
'Pending' ELSE 'Completed' End AS overall_status
There is two solutions as I see it:
1. You make the current query a subquery and add another CASE statement on the result of the subquery. (the pretty solution as I see it)
2. You add another WHEN to the existing case. Combining the clauses in the first two WHEN clauses to get the result. (probably the most optimized solution)
How about this?
(case when (cust_shipmentdate_awb Is Null OR cust_shipmentdate_awb = '') and
(comp_shipdate_awb IS NULL OR comp_shipdate_awb = '')
then 'Not Completed'
when apbg_bal_pay_amt = '0' Then 'Completed'
else 'Not Completed'
end) as overall_status

SSRS - Display Blank Values

Parameter Values
I am trying to display all the records with any status. When the user select 'AllLogs' from the dropdwon in report.
But when I run the report it is excluding the records with blank
status.
How can i pull the records with any status(blank,NULL,Approved,etc) ?
Label: Status
Value: %
I have also enabled NULL and Blank values in the parameter properties.
This is my where clause.
( ( l.Status LIKE '%' + #status + '%' ) OR
( l.Status LIKE #status ) OR
( LTRIM(RTRIM(l.Status))='') OR
( l.status IS NULL ) )
The most surefire way to include all records is to simply not filter in your where, which can be achieved with a short-circuiting case statement:
where case when #status = '%' -- This can be any value, such as 'All'
then 1
else case when l.Status = #status
then 1
else 0
end
end = 1
Whilst this is a little verbose, it has the added benefit of not actually running the comparison if your All option is selected, which will improve query performance.

Select a 'virtual' column if another column has a value or is null in a SQL view

I want to select ALWAYS a column in my view, and set it with CASES.
example:
SELECT isDone
,doneN
from...
I have to set isDone in this way:
if done is 1 isDone is 'yes'
if done is 0 isDone is 'no'
(doneN is a column from another table, isDone instead doesn't exist in other tables, so it's a "virtual" column)
Thank you in advice
Is this what you want?
select (case when doneN = 1 then 'yes' else 'no' end) as isDoneN
. . .
You didn't specify whether 'done' will always be 0 or 1. If there are more values or you want to catch other values, use something like this:
select (case when done = 1 then 'yes'
when done = 0 then 'no'
else '' end) as isDone
, doneN
from ...
If the 'done' is constrained to be 0 or 1, you can use:
select (case when done = 1 then 'yes'
else 'np' end) as isDone
, doneN
from ...

How to specify an array in the Where clause using Moodle DB API Call?

I want to filter data based on an array, similar to "in" keyword in a query:
SELECT count(*) as number_of_records,
count(CASE WHEN result = 'SUCCESS' THEN 1 END) as successful_builds_no,
min(CASE WHEN result = 'FAILURE' THEN 0 ELSE 1 END) as is_success,
min(duration) as best_duration,
max(build_date) as build_date
FROM mdl_selenium_results
WHERE build_date in ('2014-03-13', '2014-03-12')
GROUP BY build_date
How to achieve that using Moodle DB api??
If you are creating an SQL query to use within Moodle, you could just use the IN keyword, exactly as you have done in the example.
Alternatively, to make it a bit more cross-DB compatible, and to make your queries run a bit faster when there is only one item in the list, you can write:
list($dsql, $dparam) = $DB->get_in_or_equal(array('2014-03-13', '2014-03-12'), SQL_PARAMS_NAMED);
$sql = "SELECT count(*) as number_of_records,
count(CASE WHEN result = 'SUCCESS' THEN 1 END) as successful_builds_no,
min(CASE WHEN result = 'FAILURE' THEN 0 ELSE 1 END) as is_success,
min(duration) as best_duration,
max(build_date) as build_date
FROM {selenium_results}
WHERE build_date $dsql
GROUP BY build_date";
$result = $DB->get_records_sql($sql, $dparams);
OR, if you just want to get all the matching records from the given table (and then worry about doing the calculations in PHP), you could write:
$result = $DB->get_records_list('selenium_results', 'build_date', array('2014-03-13', '2014-03-12'));
(I've not run any of the code above, so apologies for any typos)