SQL IF else select clause - sql-server

I need to be able to do an IF ELSE in the having clause of a select statement. Here is an excerpt of what I am trying to do:
HAVING
IF #Vendor IS NOT NULL
THEN (COUNT(Iron_1.SN) > 0) AND [User].UserIdentifier = #Vendor AND Location_1.LocationName = #LocationName
ELSE
(COUNT(Iron_1.SN) > 0) AND Location_1.LocationName = #LocationName
I want certain filters based on if the user provided a value for a query parameter or not.

Try this instead
HAVING COUNT(Iron_1.SN) > 0 AND Location_1.LocationName = #LocationName AND
(#Vendor IS NULL OR (#Vendor IS NOT NULL AND [User].UserIdentifier = #Vendor))
or this slightly simplier version
HAVING COUNT(Iron_1.SN) > 0 AND Location_1.LocationName = #LocationName AND
(#Vendor IS NULL OR [User].UserIdentifier = #Vendor)
try the two and go for the one you like the best and works

Related

SQL: how to do an IF check for data range parameters

I am writing a stored procedure that takes in 4 parameters: confirmation_number, payment_amount, start_range, end_range.
The parameters are optional, so I am doing a check in this fashion for the confirmation_number, and the payment_amount parameters:
IF (#s_Confirmation_Number IS NOT NULL)
SET #SQL = #SQL + ' AND pd.TransactionNumber = #s_Confirmation_Number'
IF (#d_Payment_Amount IS NOT NULL)
SET #SQL = #SQL + ' AND pd.PaymentAmount = #d_Payment_Amount'
I would like to ask for help because I am not sure what is the best method to check for the date range parameters.
If someone could give me en example, or several on how this is best achieved it would be great.
Thank you in advance.
UPDATE - after receiving some great help -.
This is what I have so far, I am following scsimon recommendation, but I am not sure about the dates, I got the idea from another post I found and some playing around with it. Would you care looking at it and tell me what you all think?
Many thanks.
#s_Confirmation_Number NVARCHAR(50) = NULL
, #d_Payment_Amount DECIMAL(18, 2) = NULL
, #d_Start_Range DATE = NULL
, #d_End_Range DATE = NULL
...
....
WHERE
ph.SourceType = #s_Source_Type
AND ((pd.TransConfirmID = #s_Confirmation_Number) OR #s_Confirmation_Number IS NULL)
AND ((pd.PaymentAmount = #d_Payment_Amount) OR #d_Payment_Amount IS NULL)
AND (((NULLIF(#d_Start_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) >= #d_Start_Range)
AND ((NULLIF(#d_End_Range, '') IS NULL) OR CAST(pd.CreatedDate AS DATE) <= #d_End_Range))
(The parameter sourceType is a hard-coded value)
This is called a catch all or kitchen sink query. It is usually written as such:
create procedure myProc
(#Payment_Amount int = null
,#Confirmation_Number = null
,#start_range datetime
,#end_range datetime)
as
select ...
from ...
where
(pd.TransactionNumber = #Confirmation_Number or #Confirmation_Number is null)
and (pd.PaymentAmount = #Payment_Amount or #Payment_Amount is null)
The NULL on the two parameters gives them a default of NULL and makes them "optional". The WHERE clause evaluates this to only return rows where your user input matches the column value, or all rows when no user input was supplied (i.e. parameter IS NULL). You can use this with the date parameters as well. Just pay close attention to your parentheses. They matter a lot here because we are mixing and and or logic.
Aaron Bertrand has blogged extensively on this.
I do it like this
WHERE
COALESCE(#s_Confirmation_Number,pd.TransactionNumber) = pd.TransactionNumber AND
COALESCE(#d_Payment_Amount,pd.PaymentAmount) = pd.PaymentAmount
If we have a value for each of these parameters then it will check against the filter value otherwise it will always match the filter value if the parameter is null.
I've found that using COALESCE is faster and clearer than IF control statements or using OR in the WHERE clause.
There is another way.
But I tested and realized that a scsimon query is faster than mine.
AND (CASE
WHEN #Confirmation_Number is not null
THEN (CASE
WHEN pd.TransactionNumber = #Confirmation_Number
THEN 1
ELSE 0
END)
ELSE 1
END = 1)

How to create drop-down list in SSRS based on WHERE clause below?

At my organization we using UI third party tool that communicates with SQL database. I have access to a database, but not to the tool.
Based on a stored procedure below user able to choose from drop-down list DairyStatus "Open", "Closed", or "Both"
ALTER Procedure
AS
#ShowOpen bit = 0,
#ShowClosed bit = 0
SELECT
FROM
WHERE
AND
(
(CASE WHEN (#ShowOpen = 1) THEN
CASE WHEN (tblNoteRecipients.CompletedDate IS NULL and tblNoteRecipients.IsDiary = 1) or tblNoteRecipients.UserGUID is null THEN 1 ELSE 0 END
ELSE
1
END = 1)
AND
(CASE WHEN (#ShowClosed = 1) THEN
CASE WHEN (tblNoteRecipients.CompletedDate IS NULL) THEN 0 ELSE 1 END
ELSE
1
END = 1)
OR ((#ShowOpen = 1) AND (#ShowClosed = 1))
)
So my question is how can I make same drop-down list in SSRS?
What would be the data-set in order to populate this drop-down list?
create a parameter in ssrs with 3 static values(open closed both)
in where clause it should be something like :
( #DairyStatus = 'open' and ((tblNoteRecipients.CompletedDate IS NULL and tblNoteRecipients.IsDiary = 1) or tblNoteRecipients.UserGUID is null)) or
( #DairyStatus = 'closed' and tblNoteRecipients.CompletedDate IS not NULL) or
#DairyStatus = 'both'

Conditional WHERE clause to combine two queries

I have a large SELECT INTO statement in a T-SQL script and currently I have two separate SELECT INTO's only differing by one OR condition in the WHERE clause. If my variable #cycle_nbr = 1 I have it doing one SELECT INTO, if #cycle_nbr = 0 I have it doing the other SELECT INTO.
I was wondering if there was a way to do this in one SELECT INTO with the #cylce_nbr condition in the WHERE itself.
Here is my WHERE clause:
WHERE ((a.gl_indicator = '0' OR a.gl_indicator = '1')
AND (a.gl_ins_type = '1' OR a.gl_ins_type = '3' )
AND rel_file_nbr is NULL
AND a.alpha_line NOT LIKE '%Z'
AND mis_process_dt >= #start_dt
and acctg_cyc_ym = #acctg_cyc)
OR (a.prem_sys_cd='T' AND acctg_cyc_ym = #acctg_cyc )
I only want this last condition OR (a.prem_sys_cd='T' AND acctg_cyc_ym = #acctg_cyc ) in there if #cycle_nbr = 1. Can I put an IF in there somewhere to make this work? Or do I have to stick with the IF(#cycle_nbr = 1) run this select ELSE run the other select?
Include your variable in the OR statement, i.e.,
OR (a.prem_sys_cd='T' AND acctg_cyc_ym = #acctg_cyc AND #cycle_nbr = 1)

How to get all values including null in a SQL Server case statement?

I have a big stored procedure, and basically I want to select all values (including null) if my variable #DimBrowserId is set to 0. I am using a case statement, however this is only catching values that actually have something and ignoring the NULL valued fields. Because I am using the = clause in the WHERE I cannot do IS NULL. I do not want to have to write 2 IF statements because the stored procedure would then be enormous, so I want to know how to get null values as well. Here is my code:
SELECT
DATEPART(yy, DATEADD(mi, #Mdelta, d.DimDateValue)),
DisableCount = COUNT(*)
FROM
dbo.FactDisable AS f
JOIN
dbo.DimDate AS d ON f.DimDateId = d.DimDateId
JOIN
dbo.DimDevice AS v ON f.DimDeviceId = v.DimDeviceId
WHERE
d.DimDateValue >= #StartDateGMT
AND d.DimDateValue <= #EndDateGMT
AND f.IsTest = #IncludeTest
AND f.DimProductId = #DimProductId
AND v.DimBrowserId = CASE
WHEN #DimBrowserId = 0 THEN v.DimBrowserId
ELSE #DimBrowserId
END
GROUP BY
DATEPART(yy, DATEADD(mi, #Mdelta, d.DimDateValue))
The code is near the CASE clause.
Thanks
Change that line to be
AND (#DimBrowserID = 0 OR #DimBrowserID = v.DimBrowserId)
If #DimBroserID is 0 then no filtering will be applied for this line.
Use ISNULL:
SELECT DATEPART(yy,DATEADD(mi,#Mdelta,d.DimDateValue)),
DisableCount=COUNT(*)
FROM dbo.FactDisable AS f
JOIN dbo.DimDate AS d ON f.DimDateId = d.DimDateId
JOIN dbo.DimDevice AS v ON f.DimDeviceId = v.DimDeviceId
WHERE d.DimDateValue >= #StartDateGMT AND d.DimDateValue <= #EndDateGMT
AND f.IsTest = #IncludeTest AND f.DimProductId = #DimProductId
AND v.DimBrowserId = CASE WHEN ISNULL(#DimBrowserId,0) = 0 THEN v.DimBrowserId ELSE #DimBrowserId END
GROUP BY DATEPART(yy,DATEADD(mi,#Mdelta,d.DimDateValue))
CASE WHEN COALESCE(#MightBeNull, 0) = 0 THEN ZeroResult ...
will be treated as zero if #MightBeNull is null, and whatever #MightBeNull is if it's not null.
Assuming null means any browser, a better data model for this scenario might be to set an ID that identifies any browser, instead of setting it to null.
You probably know what you are running into is NULL does not equal NULL in a comparison.
Assuming you don't have control of the data model to fix that, one option would be to coalesce your NULL values to an unused id.
The resulting WHERE clause would look like this, assuming -1 is the unused value you choose.
AND COALESCE(v.DimBrowserId, -1) = CASE WHEN #DimBrowserId = 0 THEN COALESCE(v.DimBrowserId, -1) ELSE #DimBrowserId END

Not sure how to approch this, doing some math with error checking and updating my new value in tsql

if (freightCostTotal == 0)
{
freightCount = 1;
dataGridView1.Rows[i].Cells[iFreightCount].Value = "1";
if (freightCostDefinedTotal != 0)
{
freightCostTotal = Convert.ToDecimal(pcsg.Freight_CountColumn.Table.Rows[0]["Fixed Freight"].ToString());
}
else
{
if (!String.IsNullOrEmpty(dataGridView1.Rows[i].Cells[iCost_Prior_ReCompute].Value.ToString()))
Cost_Prior_ReCompute = Convert.ToDecimal(dataGridView1.Rows[i].Cells[iCost_Prior_ReCompute].Value.ToString());
//freightCostPercentTotal = 0.05M;
//decimal costFreight = Convert.ToDecimal(pcsg.Freight_CountColumn.Table.Rows[0]["Cost"].ToString());
freightCostTotal = (Cost_Prior_ReCompute * freight_perc_);
}
dataGridView1.Rows[i].Cells[iFreight].Value = String.Format("{0:0.00}", freightCostTotal);
}
The following is not working. This is my first attempt at doing sql math
select freightCostTotal, Cost_Prior_ReCompute],freight_perc_, FixedFreight,
if (freightCostTotal == 0) then freightCount = 1;
if (freightCostDefinedTotal != 0) then freightCostDefinedTotal = FixedFreight else
set freightCostTotal = (Cost_Prior_ReCompute * freight_perc_);
from VF_CasINV_Cost
Thanks,
Jerry
Not sure what you're after exactly, but here's a start below. FYI -- your conditional on Cost_Prior_Recompute needs a default / else value -- I just put a '?' in there for now, since I can't tell what it should be.
Also -- I can't tell if freigntCostTotal is an actually field in your database that you're trying to update, or if you plan to just compute it based on other fields each time. So far, I'm assuming you're just going to compute it.
So this is how you would select -- keeping in mind (I assume from reading your code) you are looking for data where the frieghtCostTotal has NOT been updated in the database yet.
SELECT
1 as freightCount,
CASE WHEN freightCostDefinedTotal <> 0
THEN FixedFreight
ELSE ISNULL(Cost_Prior_ReCompute,?) * freight_perc_
END as freigntCostTotal,
Cost_Prior_ReCompute,
freight_perc_,
FixedFreight
FROM
VF_CasINV_Cost
WHERE
freightCostTotal = 0
Alternatively, you could just pull the data out like this, but it will get all data, not just the freightCostTotal = 0 data.
SELECT
1 as freightCount,
freigntCostTotal,
Cost_Prior_ReCompute,
freight_perc_,
FixedFreight
FROM
VF_CasINV_Cost
Here's how you would update. BTW -- If you're new to updating with SQL, I'd highly recommend you test this out on some non-production data first. Or at least, back-up your table first.
UPDATE VF_CasINV_Cost
SET freightCostTotal = CASE WHEN freightCostDefinedTotal <> 0
THEN FixedFreight
ELSE ISNULL(Cost_Prior_ReCompute,?) * freight_perc_
END
WHERE freightCostTotal = 0

Resources