Here is a sample code:
select i.computerguid, i.logfile_enabled, i.logfile_logExtFileFlags
,Case
When
CHARINDEX('Date' , i.logfile_logExtFileFlags) = 0 or
CHARINDEX('Time' , i.logfile_logExtFileFlags) = 0 or
CHARINDEX('ClientIP', i.logfile_logExtFileFlags) = 0
Then 'Need these W3SVC fields enabled by default: Date, Time, ClientIP'
End as 'Reason'
,Case When i.logfile_enabled = 'true' Then 'Enabled the IIS log fields (via IIS MMC console) for site: ' + i.sitename End as 'Remediation'
from aspr_iissite i inner join aspr_root r on r.computerguid = i.computerguid
where i.logfile_enabled = 'true'
Here is a screen shot, I dont want to display the rows when 'Reason' is NULL:
Thank you
In your case, it is easiest to use a subquery:
select *
from (select i.computerguid, i.logfile_enabled, i.logfile_logExtFileFlags,
(Case When CHARINDEX('Date' , i.logfile_logExtFileFlags) = 0 or
CHARINDEX('Time' , i.logfile_logExtFileFlags) = 0 or
CHARINDEX('ClientIP', i.logfile_logExtFileFlags) = 0
Then 'Need these W3SVC fields enabled by default: Date, Time, ClientIP'
End) as Reason,
(Case When i.logfile_enabled = 'true'
Then 'Enabled the IIS log fields (via IIS MMC console) for site: ' + i.sitename
End) as Remediation
from aspr_iissite i inner join
aspr_root r
on r.computerguid = i.computerguid
where i.logfile_enabled = 'true'
) ir
where Reason is not null;
You could repeat the conditions in the case statement, but that makes the code harder to modify and maintain.
Two notes:
I think it is easier to follow the conditional logic using like: i.logfile_logExtFileFlags not like '%Date%'`. This is standard SQL.
Only use single quotes for string and date constants. Don't use them for column aliases.
Related
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?
In production we have 3 shifts. Each Shift timing is described in table tbl_ShiftSched:
WT - work time, PT - break time.
ShiftTmID - schedule for 2 and for 3 shifts.
I am looking for easy way to get work time in minutes having start and end time.
For example, having input between #2015.05.29 06:10:00# and #2015.05.29 09:30:00# and tbl_WorkStations.WksID='GRD' (Workstation code with relation on ShiftTmID ='3P') should give output 190 min.
I have function in MS Access which gives me needed output. But when migrated to T-SQL it becomes very complicated because I do not find easy way how to use alias in T-SQL. Here is the code:
USE [STRDAT]
GO
declare
#strWks varchar(3),
#dteIN datetime='2013.08.05 03:30',
#dteOUT datetime='2013.08.05 05:30',
#strShf varchar(12)=null,--'2013.08.04-3',
#strInd varchar(2) = 'WT',
#dteFTm datetime,
#dteShf date
--#PrdS datetime,
--#PrdE datetime
select top 1
#dteFTm =
case
when #strShf is not null
then (select shiftstart from tbl_ShiftSched where ShiftTmID=(select ShiftTiming from tbl_WorkStations where WksID=#strWks) and shift=right(#strshf,1) and sortind=1)
else #dteIN-dateadd(day,datediff(day,0,#dteIN),0) --CAST(#dteIN-cast(floor(#dteIN) as float) as datetime)
end,
#dteShf=
case
when #strShf is not null
then left(#strShf,10)
else convert(varchar,dateadd(day,datediff(day,0,#dteIN),0),102)
end
--select #dteftm,#dteShf
SELECT tbl_ShiftSched.Shift,
tbl_ShiftSched.SortInd,
[ShiftStart]+
case
when #dteFTm>[shiftstart]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdS,
[ShiftEnd]+
case
when #dteFTm>[shiftend]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdE,
case
when #dteIN>=[PrdS] AND [PrdE]>=#dteOUT
then DateDiff(minute,#dteIN,#dteOUT)
else case
when #dteIN<=[PrdS] AND [PrdE]<=#dteOUT
then DateDiff(minute,[PrdS],[PrdE])
else case
when [PrdS]<=#dteIN AND #dteIN<=[PrdE]
then DateDiff(minute,#dteIN,[Prde])
else case
when [PrdS]<=#dteOUT AND #dteOUT<=[PrdE]
then DateDiff(minute,[Prds],#dteOUT)
else 0
end
end
end
end AS Tm,
#dteIN AS S,
#dteOUT AS E,
tbl_ShiftSched.ShiftType,tbl_ShiftSched.ShiftStart,tbl_ShiftSched.ShiftEnd
FROM tbl_WorkStations
INNER JOIN tbl_ShiftSched ON tbl_WorkStations.ShiftTiming = tbl_ShiftSched.ShiftTmID
WHERE (((tbl_WorkStations.WksID)=#strWks))
Off course it gives me an error Invalid column name 'PrdS' and 'PrdE' because I use alias.
Must be some more easy way to achieve it. Maybe I am on wrong direction?...
Whenever I have to calculate a field and use the results in a second field, I use a common table expression to make the first calculation. Given this query, it could look like this:
with cte_preprocess as
(
SELECT tbl_ShiftSched.Shift,
tbl_ShiftSched.SortInd,
[ShiftStart]+
case
when #dteFTm>[shiftstart]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdS,
[ShiftEnd]+
case
when #dteFTm>[shiftend]
then DateAdd(day,1,#dteShf)
else #dteShf
end AS PrdE,
tbl_ShiftSched.ShiftType,tbl_ShiftSched.ShiftStart,tbl_ShiftSched.ShiftEnd
FROM tbl_WorkStations
INNER JOIN tbl_ShiftSched ON tbl_WorkStations.ShiftTiming = tbl_ShiftSched.ShiftTmID
WHERE (((tbl_WorkStations.WksID)=#strWks))
)
SELECT [Shift]
, SortInd
, PrdS
, PrdE
, case
when #dteIN>=[PrdS] AND [PrdE]>=#dteOUT
then DateDiff(minute,#dteIN,#dteOUT)
else case
when #dteIN<=[PrdS] AND [PrdE]<=#dteOUT
then DateDiff(minute,[PrdS],[PrdE])
else case
when [PrdS]<=#dteIN AND #dteIN<=[PrdE]
then DateDiff(minute,#dteIN,[Prde])
else case
when [PrdS]<=#dteOUT AND #dteOUT<=[PrdE]
then DateDiff(minute,[Prds],#dteOUT)
else 0
end
end
end
end AS Tm
, #dteIN
, #dteOUT
, ShiftEnd
FROM cte_preprocess
More on CTE's here
I want to use case after where clause in SQL Server 2008; how can I use it like
select *
from MPR
where
case when #min >= 0
then MainComponent_Id = #mainc and SubComponent_Id = #subcomp
else MainComponent_Id = #mainc and SubComponent_Id = #subcomp and MinorComponent_Id = #minorc
end
end
I am using a stored procedure, and in my stored procedure if minorcomponent_id value is 0 then it will add 1 one else 2 one will work.
I had tried hard but its giving error in near case.
How to resolve it?
Thanks
You don't need to use a CASE statement. You can simplify logic as follows:
select
*
from
MPR
where
MainComponent_Id = #mainc AND SubComponent_Id = #subcomp
AND (#min >= 0 OR MinorComponent_Id = #minorc)
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.
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