Using SELECT subquery in a CASE statement and handling NULLS - sql

I have 2 SQL tables one holding stock information then a style table which details how the stock is used. For some jobs the information is contained with a print file so the value in the stock table would be BIN, if not it would contain a template name which would cause a query to a Styles table which then shows how the stock is used. There a 10 positions that a stock could be applied but the template table wouldn't have records for where a stock couldn't be used (on the back of a simplex job for example).
I have a stored procedure which works to provide the detail based on whether the logic value is BIN or not but for the records in the style table that have no value I get NULL back which I need to suppress but just putting ISNULL around the column name in the subquery isn't having any effect. Am I just missing something as I'd rather not nest in another CASE statement to check if the query would produce NULL
WITH STYLES AS
(
SELECT
#JOBNAME AS JobName, Logic AS StyleName
FROM
[dbo].[CON_Tbl_511_DigitalStocks]
WHERE
JOBNAME = #JOBNAME
)
SELECT TOP 1
[Logic],
[S1F], [S1B], [S2F], [S2B],
[S3F], [S3B], [S4F], [S4B],
[S5F], [S5B],
CASE
WHEN b.stylename = 'BIN'
THEN --checks if there is a style for this job
CASE
WHEN S1F = '' THEN ''
ELSE '1'
END -- if a stock code is specified then return the bin name ("1")
ELSE (SELECT PAGE
FROM [dbo].[CON_Tbl_512_DigitalLogic]
WHERE STYLENAME = B.StyleName
AND STOCKREF = 'S1F')
END AS S1F_LOGIC, -- If a style is used return the style instruction for this bin and side
CASE
WHEN b.stylename = 'BIN' -- repeat this for all bins/sides
THEN
CASE WHEN S1B = '' THEN ''
ELSE '1'
END
ELSE (SELECT PAGE
FROM [dbo].[CON_Tbl_512_DigitalLogic]
WHERE STYLENAME = B.StyleName AND STOCKREF = 'S1B')
END AS S1B_LOGIC,
CASE WHEN b.stylename = 'BIN' THEN
CASE WHEN S2F = '' THEN ''
ELSE '2' END
ELSE (SELECT PAGE FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F') END AS S2F_LOGIC -- this one returns NULL as there is no instruction required for "2SF"
FROM
[CON_Tbl_511_DigitalStocks] A
JOIN
STYLES B ON A.JOBNAME = B.JOBNAME
WHERE
A.JobName = #JobName
This code works fine until the last one as there is no value in the stockref column that says 'S2F' but putting SELECT ISNULL(PAGE, '') still returns NULL

Because this query is not finding any records:
SELECT PAGE FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F'
and you want it to return something, you can change it to:
SELECT coalesce(min(PAGE),'') FROM [dbo].[CON_Tbl_512_DigitalLogic] WHERE STYLENAME = B.StyleName AND STOCKREF = 'S2F'
This will return the minimum value (min) of the found records, which will return NULL when noting found. The coalesce will turn this NULL into the empty string: ''
P.S.: see also SQL - Difference between COALESCE and ISNULL?

Related

SELECT WHERE {column} = CASE WHEN {expression} THEN NULL

I have this code which is part of a stored procedure
INSERT INTO #TempTable
/* A few subqueries, about 100 lines */
WHERE (cartera.ClaSucursal = #pIdSucursal OR #pIdSucursal = -1)
AND (cartera.ClaAsesorActual =
CASE
WHEN #pIdAsesor > 0 THEN #pIdAsesor
WHEN #pIdAsesor = 0 THEN NULL
END
OR #pIdAsesor = -1)
/* Rest of my code, about 200 lines */
SELECT * FROM #TempTable
Basically I have a parameter called #pIdAsesor and depending on its value there can be three possible outcomes.
#pIdAsesor = -1 which brings me all entries regardless of the Id value
#pIdAsesor = sumId which brings me all entries with given Id
#pIdAsesor = 0 which brings me all entries with NULL as the Id
Outcomes 1 and 2 work flawlessly, but scenario 3 doesn't bring back results.
null isn't a value - it's the lack thereof. null is never equal to anything (not even another null), but you can check for it explicitly with the is operator.
You could ditch the case expression and construct this logic with a series of ors:
AND ((#pIdAsesor = -1) OR
(#PIdAsesor = 0 AND cartera.ClaAsesorActual IS NULL) OR
(#pIdAsesor = cartera.ClaAsesorActual))
You can't use = for null in case when result comes null but = null doesn't work. You have to use is null.

Validating a record to see if it only contains digits

I am validating VAT codes. The codes include GB in front of them but i would like to not include that and see if the rest of the vat code only includes numbers.
select KUNNR,VAT_CODE,REPLACE(VAT_CODE,'GB',''),
CASE WHEN REPLACE(VAT_CODE,'GB','') LIKE '%[^0-9]%' THEN 'Yes' ELSE 'No' END as VAT_MATCH
FROM CUSTOMER_TBL;
"customer" "VAT" "REPLACE(VAT,'GB','')" "VAT_MATCH"
"0063591544" "GB111111111" "111111111" "No"
This is how I would do it:
-- Sample Data
DECLARE #CUSTOMER_TBL TABLE (VAT_CODE VARCHAR(36));
INSERT #CUSTOMER_TBL VALUES ('GB123111GB'),('GB9999111'),('GBB9999111'),('GGB7777222'),
('553399444'),('GB22223366'),('GB22223366X')
-- solution
SELECT t.VAT_CODE, VAT_MATCH = IIF(f.H = 'GB' AND PATINDEX('%[^0-9]%',f.B) = 0,'Yes','No')
FROM #CUSTOMER_TBL AS t
CROSS APPLY (VALUES (SUBSTRING(t.VAT_CODE,1,2),SUBSTRING(t.VAT_CODE,3,8000))) AS f(H,B);
/* For pre-2012 systems:
VAT_MATCH = CASE WHEN f.H = 'GB' AND PATINDEX('%[^0-9]%',f.B) = 0 THEN 'Yes' ELSE 'No' END */;
Results
VAT_CODE VAT_MATCH
------------------------------------ ---------
GB123111GB No
GB9999111 Yes
GBB9999111 No
GGB7777222 No
553399444 No
GB22223366 Yes
GB22223366X No

Variable is getting NULL after SUM function in SQL Server

I have this code that is part of a stored procedure:
SET #_Value = 0
SET #_Cont = 1;
IF(#_FlagControl = 1)
BEGIN
SELECT #_Value = SUM(Value)
FROM Person P
INNER JOIN Order O on O.CodPerson = P.CodOrder
WHERE P.CodPerson = #_CodP
AND P.CodImp <> 3
AND P.FlagSituation = 1
AND #_CodMainPerson = P.CodPerson
IF(#_Value IS NULL)
PRINT 'NULL'
ELSE
PRINT #_Value
END
If I run just this SELECT inside the "IF", it returns '0.90'. But when I run this entire query inside a procedure, it is printing NULL.
I don't have idea what is going on.
You assign #_Value
You check #_Value
You print #_ValorImposto
So if #_Value is not null, you don't print it...
Edit, it is not this
Therefore, the SELECT has no rows, which when SUMMed gives one row, making #_Value NULL
So test and fix the SELECT in the stored procedue: print #_CodP and #_CodMainPerson. SELECT without the SUM.
Not in another query with hardcoded values: this proves nothing
Note that SUM without GROUP BY always returns exactly one row.
So #_Value will always either either a non-null value or NULL
See Does COUNT(*) always return a result? for more

conditional handling of update sql script depending on input parameter

I am new to SQL and using Oracle 11. I need to write a sql script which uses different update command based on whether the input param is null or not null.
I need something like this
['&' followed by the parameter name is the way i see parameters being used in other such
script for our project]
IF &PRG_ID IS NULL
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
ELSE
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE
P.PROGRAM_ID = &PRG_ID AND EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID);
END IF;
Something like (is not tested):
UPDATE PROGRAM_TABLE P SET HANDLED_IND = 'Y' WHERE EXISTS
(SELECT 1 FROM HANDLED_PROGRAM H WHERE H.PROGRAM_ID = P.PROGRAM_ID)
AND (&PRG_ID IS NULL OR P.PROGRAM_ID = &PRG_ID);
But take into account this change may lead to the performance degradation for the case when PRG_ID has definite value.

ISNULL, SQL, Using a select statement as the second parameter

I don't know if this is possible in SQL or if I have to write a stored procedure but I'm trying to use the ISNULL function as below so that when the parameter #sku is null I'm using a select statement to bring back all the sku's in the table:
SELECT GooglePrice.idGooglePrice, GooglePrice.idProduct, products.sku, products.wholeprice, products.price as CurrentHMMPrice, GooglePrice.bestPrice, GooglePrice.link, GooglePrice.title, GooglePrice.description, GooglePrice.ourPrice as PriceCompHMMPrice,
GooglePrice.searchType, GooglePrice.shippingCost, GooglePrice.cheapestOrder, GooglePrice.timeStamp,
'ShippingCostNew' = CASE
WHEN GooglePrice.shippingCost = -1 THEN 'N/A'
WHEN GooglePrice.shippingCost = 0 THEN 'Free Shipping'
WHEN GooglePrice.shippingCost > 0 Then cast(GooglePrice.shippingCost as varchar)
END
FROM GooglePrice INNER JOIN
products ON GooglePrice.idProduct = products.idProduct
WHERE (products.supplierCode in (#SupplierCode)) AND ISNULL((products.sku like '%'+#sku+'%'), (products.sku in (select sku from products where products.sku)))
ORDER BY GooglePrice.idGooglePrice
Would be easier with an OR
WHERE
(products.supplierCode in (#SupplierCode))
AND
(products.sku like '%'+#SupplierCode+'%' OR #SupplierCode IS NULL)
This was your intention, no?
AND
products.sku like ISNULL('%'+#SupplierCode+'%',products.sku)
Notes:
leading wildcards can not be optimised and won't use indexes.
I assume you don't have a CSV in #SupplierCode for this products.supplierCode in (#SupplierCode)
Don't overcomplicate it.
Make your WHERE clause:
WHERE
((products.supplierCode in (#SupplierCode)
AND
(products.sku like '%'+#SupplierCode+'%'))
OR (#suppliercode IS NULL)
You don't really explain your logic so I'm guessing, but the idea is to put a separate check for the NULL comparison.
SELECT GooglePrice.idGooglePrice, GooglePrice.idProduct, products.sku, products.wholeprice, products.price as CurrentHMMPrice, GooglePrice.bestPrice, GooglePrice.link, GooglePrice.title, GooglePrice.description, GooglePrice.ourPrice as PriceCompHMMPrice, GooglePrice.searchType, GooglePrice.shippingCost, GooglePrice.cheapestOrder, GooglePrice.timeStamp,
'ShippingCostNew' = CASE
WHEN GooglePrice.shippingCost = -1 THEN 'N/A'
WHEN GooglePrice.shippingCost = 0 THEN 'Free Shipping'
WHEN GooglePrice.shippingCost > 0 Then cast(GooglePrice.shippingCost as varchar)
END
FROM GooglePrice INNER JOIN
products ON GooglePrice.idProduct = products.idProduct
WHERE (products.supplierCode in (#SupplierCode)) AND (#SupplierCode is null or products.sku like '%'+#SupplierCode+'%')
ORDER BY GooglePrice.idGooglePrice