Why these two cases are not equivalent - sql-server

I have written a sql query that check is #Collegein not equals to 0, if so then get college_code according to that else go for all colleges.I have already used this technique but never tried it for multivalues .I have this condition in "where"
College_code in (CASE WHEN #Collegein != '0' THEN (SELECT items FROM dbo.Split(#Collegein, ',')) ELSE College_code END)
This works fine for #Collegein = '1' but fails for #Collegein = '1,2' , giving error subquery return more than 1 value.
While below code works fine for #Collegein = '1,2'
College_code in (select * from dbo.Split(#Collegein ,','))
What could be that possible solution for this or alternative solution. One more thing why "in" not working here

This cannot work. While IN clearly deals with multiple values, CASE can return only a single value. Therefore the subquery in your case is expected to return a single value and that's why you get the error. You have to use OR here:
#Collegein = '0'
OR
(
#Collegein != '0'
AND College_code IN(SELECT items FROM dbo.Split(#Collegein, ','))
)

Try this:
#Collegein = '0'
OR
EXISTS(SELECT items FROM dbo.Split(#Collegein, ',') WHERE Items = College_code)
Addition(based on Thomas's answer):
#Collegein = '0'
OR
College_code IN(SELECT items FROM dbo.Split(#Collegein, ','))

Related

SQL Server : Subselect where IS NULL THEN 'VALUE'

I am trying to return a string result when a value IS NULL in SQL Server.
An example of what I am doing is below. This is a sub select query...
SELECT
stockitems.code AS StockCode,
stockitems.description AS
ShortDescription,
(SELECT
CASE remaining
WHEN NULL
THEN 'NO LEVEL'
ELSE remaining
END
FROM StockItemAlertLevels
WHERE StockItems.ID = StockItemAlertLevels.StockItemID) AS RemainingLevel
FROM
stockitems
WHERE
StockItems.Attribute1 = '1'
ORDER BY
StockItems.Code
No matter what I do, I cannot get the output result of the subselect to change if the result is NULL. Not all returned results from the SELECT statement will have returned results in the subselect - this is where I need the set the output to "NO LEVEL". The subselect will never return more than one result.
Hope this makes sense.
I think you want COALESCE():
SELECT si.code As StockCode, si.description AS ShortDescription,
(SELECT COALESCE(remaining, 'NO LEVEL')
FROM StockItemAlertLevels sal
WHERE si.ID = sal.StockItemID
) as RemainingLevel
FROM stockitems si
WHERE si.Attribute1 = '1'
ORDER BY si.Code;
I suspect, though, that your problem is not that remaining is NULL, but that there are no matches. You can move the COALESCE() outside the subquery, but I would propose a LEFT JOIN:
SELECT si.code As StockCode, si.description AS ShortDescription,
COALESCE(remaining, 'NO LEVEL') as RemainingLevel
FROM stockitems si LEFT JOIN
StockItemAlertLevels sal
ON si.ID = sal.StockItemID
WHERE si.Attribute1 = '1'
ORDER BY si.Code;

Second Order By overrides first in SQL Server

In the following code the purchase_price overrides the case order by statement.
SELECT
i.products_mpn, i.active,
i.distributor_code, i.sales_price
FROM
#duplicates d
LEFT JOIN
import i ON i.products_mpn = d.products_mpn
AND i.distributor_code = (SELECT TOP 1 distributor_code
FROM dbo.kting_ICECAT_import
WHERE products_mpn = d.products_mpn
ORDER BY
(SELECT
CASE
WHEN (i.distributor_code = 'x' or i.distributor_code = 'y') AND CAST(stock as int) > 0
THEN 2
WHEN CAST(stock as int) > 0
THEN 1
ELSE 0
END) DESC,
CAST(purchase_price AS decimal(28,12)))
Is there any way to get it to work with ordering by the case statement and then the purchase_price?
If you want the ordering of the CASE statement to be applied first followed by the ordering of the purchase_price, then your ORDER BY already has the terms in the right place. I don't know what SELECT is doing in your CASE expression, or even if your current query runs. Something like this may be what you had in mind:
ORDER BY CASE WHEN (i.distributor_code = 'x' or i.distributor_code = 'y') AND
CAST(stock as int) > 0 THEN 2
WHEN CAST(stock as int) > 0 THEN 1
ELSE 0
END DESC,
CAST(purchase_price AS DECIMAL(28,12))
The problem was in the ORDER BY SELECT. I had used columns from the left join "i.distributor_code" should just have been distributor_code

SQL Server Remove unwanted rows from a CASE statement

I do a SELECT with a CASE statement with this following:
SELECT DISTINCT
n.NiveauId, n.Description,
CASE WHEN n.NiveauId NOT IN (SELECT ccs.idNiveau WHERE ccs.centreCout = 60001) THEN 0 ELSE 1 END AS attribue
FROM pa.dbo.Niveau n
JOIN BDC.dbo.CentreCoutSecteur ccs ON n.NiveauId = ccs.idNiveau
Explication :
In case "NiveauId" is not present in the other table, the value of "attribue" is 0. Else, if it's present, the value is 1.
This works, but every rows that contains a 1 also shows the same row with a 0.
Exemple:
How would I change the SELECT query to remove the unwanted duplicate rows that contain 0?
Thanks in advance!
Try wrapping your select in a max (if you only want the rows with the highest value for attribue.
SELECT b.NiveauID, b.Description, MAX(b.attribue)
FROM
(SELECT DISTINCT
n.NiveauId, n.Description,
CASE WHEN n.NiveauId NOT IN (SELECT ccs.idNiveau WHERE ccs.centreCout = 60001) THEN 0 ELSE 1 END AS attribue
FROM pa.dbo.Niveau n
JOIN BDC.dbo.CentreCoutSecteur ccs ON n.NiveauId = ccs.idNiveau) b
Group By b.NiveauID, b.Description

Add ORDER BY statement to SELECT statement

I have the following SELECT statement and I need to add ORDER BY [UserName].
SELECT *
FROM [UserInfo]
WHERE ([AWSAccountID] = CASE WHEN #AWSAccountID = -1 THEN [AWSAccountID]
ELSE #AWSAccountID END)
I'm having some trouble figuring out where the ORDER BY needs to go, assuming it can be added at all.
Unless I am missing something you just add your ORDER BY to the end of the query:
SELECT *
FROM [UserInfo]
WHERE ([AWSAccountID] = CASE WHEN #AWSAccountID = -1 THEN [AWSAccountID]
ELSE #AWSAccountID END)
ORDER BY [UserName]

Case not working in Exists in Sql Server

I have a scenario where i have to check a variable for it's default value, and if it has i have to check EXISTS part conditionally with Table2 and if it does not have the default value, i have to check EXISTS part conditionally with Table3.
Below is a sample code:-
SELECT * FROM tbl1 WHERE EXISTS (SELECT CASE WHEN #boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1) ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1) END)
Demo query with constants for testing purpose: -
SELECT 1 WHERE EXISTS (SELECT CASE WHEN 1 = 0 THEN (SELECT 'X' WHERE 1=0)
ELSE (SELECT 'X' WHERE 1 = 2) END)
Note: - The above query always returning 1, even not a single condition is satisfying.
I know we can use OR operator for the same and any how we can achieve it, but i really want to know that in case both the tables have no rows satisfying their particular where clause, even it's returning all the rows from Table1.
I tried to explain the same with the demo query with constant values.
Please help.
When your query doesn't find any matching records, it will basically do:
SELECT 1 WHERE EXISTS (SELECT NULL)
As a row containing a null value is still a row, the EXISTS command returns true.
You can add a condition to filter out the null row:
SELECT * FROM tbl1 WHERE EXISTS (
SELECT 1 FROM (
SELECT
CASE WHEN #boolVar = 0 THEN (SELECT 'X' FROM tbl2 WHERE tbl1.col1 = tbl2.col1)
ELSE (SELECT 'X' FROM tbl3 where tbl1.col1 = tbl3.col1)
END AS Y
) Z
WHERE Y IS NOT NULL
)
Here's an alternative, just in case:
SELECT *
FROM Table1
WHERE EXISTS (
SELECT 1
FROM Table2
WHERE #var = #defValue
AND ... /* other conditions as necessary */
UNION ALL
SELECT 1
FROM Table3
WHERE #var <> #defValue
AND ... /* other conditions as necessary */
);

Resources