SQL Server CASE clause on where inside parenthesis - sql

I have this problem in my SQL code:
I will only show my WHERE clause, because it is a bit long,
this is it:
where
((#account_status = 1027 AND a.AccountStatus = 1027 AND a.FolioNo =
#folio_no AND b.ReservationNo = #reservation_id)) OR
((#account_status = 1026 AND a.AccountStatus = 1026 AND a.FolioNo =
#folio_no AND b.ReservationNo = #reservation_id)) OR
((#account_status = 1025 AND a.AccountStatus = 1025 AND #trans_code = 1 AND
a.AccountStatementTransCode = 1 AND b.FolioNo = #folio_no AND
b.ReservationNo = #reservation_id)) OR
((#account_status = 1025 AND a.AccountStatus = 1025 AND #trans_code != 1
AND a.AccountStatementTransCode != 1 AND b.FolioNo = #folio_no AND
b.ReservationNo = #reservation_id)) OR
((a.FolioNo = #folio_no AND b.ReservationNo = #reservation_id AND
#trans_code = 2 AND a.AccountStatementTransCode = 2 AND
case
when #sub_category = 14 then i.category_id is null
else i.category_id = #sub_category
end )) OR
((a.FolioNo = #folio_no AND b.ReservationNo = #reservation_id AND
#trans_code = 3 AND a.AccountStatementTransCode = 3 AND i.category_id =
#sub_category)) OR
((a.FolioNo = #folio_no AND b.ReservationNo = #reservation_id AND
#trans_code = 4 AND a.AccountStatementTransCode = 4 AND i.category_id =
#sub_category)) OR
((a.FolioNo = #folio_no AND b.ReservationNo = #reservation_id AND
#trans_code = 5 AND a.AccountStatementTransCode = 5 AND i.category_id =
#sub_category)) OR
((a.FolioNo = #folio_no AND b.ReservationNo = #reservation_id AND
#trans_code = 6 AND a.AccountStatementTransCode = 6 AND i.category_id =
#sub_category))
I want that if input is #sub_category = 14 then it will return the category with NULL values, else it will return the #sub_category values.
How can I do that ?

Replace CASE expression logic with below
AND
1 = CASE WHEN #sub_category = 14 AND i.category_id is null
THEN 1
WHEN #sub_category <> 14 AND i.category_id = #sub_category
THEN 1
ELSE 0
END

Change your CASE to:
case
when #sub_category = 14 then null
else i.category_id = #sub_category
end

TRY THIS: Simple way, If your category_id never hold -1 or you can use the value that will never be in category_id i.e. 0,-1
AND ISNULL(i.category_id, -1) = CASE WHEN #sub_category = 14 THEN
-1
ELSE #sub_category END

Related

Filter only get one condition

I have a validation in WHERE clause like:
...
AND (#BDOnly = 0
OR [DT].[Abbreviation] = #IsBDChecked)
AND (#CDOnly = 0
OR [DT].[Abbreviation] = #IsCDChecked)
AND (#PPOOnly = 0
OR [DT].[Abbreviation] = #IsPPOChecked)
AND (#FBOMOnly = 0
OR [DT].[Abbreviation] = #IsFBOMChecked)
AND (#APOnly = 0
OR [DT].[Abbreviation] = #IsAPChecked)
AND (#COOnly = 0
OR [DT].[Abbreviation] = #IsCOChecked)
So each AND clause check if boolean is bit value is 0 or 1, if it's 0 just do any but if it's 1 it do a filter. My problem is
if I'm sending two with value 1, I mean
#BDOnly = 1 and #CDOnly = 1 it only filter one of them instead get two filters I mean:
[DT].[Abbreviation] = #IsBDChecked
and
[DT].[Abbreviation] = #IsCDChecked
What am I doing wrong? Regards
I'm going to take a guess here because there's not enough data. If you want to return a row where Abbreviation matched #IsBDChecked only when #BDOnly is set, and also another row where Abbreviation matches #IsCDChecked when #CDOnly is set, try this:
(#BDOnly = 1
AND [DT].[Abbreviation] = #IsBDChecked)
OR (#CDOnly = 1
AND [DT].[Abbreviation] = #IsCDChecked)
OR (#PPOOnly = 1
AND [DT].[Abbreviation] = #IsPPOChecked)
OR (#FBOMOnly = 1
AND [DT].[Abbreviation] = #IsFBOMChecked)
OR (#APOnly = 1
AND [DT].[Abbreviation] = #IsAPChecked)
OR (#COOnly = 1
AND [DT].[Abbreviation] = #IsCOChecked)
Small representative case:
DECLARE #ADOnly BIT = 0
, #BDOnly BIT = 1
, #CDOnly BIT = 1
, #IsADChecked NVARCHAR(100) = 'A'
, #IsCDChecked NVARCHAR(100) = 'C'
, #IsBDChecked NVARCHAR(100) = 'B'
;WITH myTable AS
(
SELECT * FROM (VALUES ('A'), ('B'), ('C')) X(Abbreviation)
)
SELECT *
FROM myTable
WHERE (#ADOnly = 1 AND Abbreviation = #IsADChecked)
OR (#BDOnly = 1 AND Abbreviation = #IsBDChecked)
OR (#CDOnly = 1 AND Abbreviation = #IsCDChecked)
Yields:
Abbreviation
------------
B
C

SQL - WHERE with CASE statement

SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
(CASE
WHEN DATALENGTH(CostRule.ModelName) = 0
THEN
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
ELSE
CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
END
)
) AS MonoCost
I want to define my where statement depending on the datalength of CostRule.ModelName. But i got an error: Incorrect syntax near '='. in CostRule.Type = 1 and i got a error in the ELSE statement.
Must be like this:
...
WHERE
(DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR
(DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
The CASE-style from your query cannot work.
you can change your statement like this:
SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE CostRule.ColorType=1
AND CostRule.Type=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN 1 ELSE 2 END
AND CostRule.Manufacturer=CASE WHEN DATALENGTH(CostRule.ModelName) = 0 THEN Printer.ManufacturerId ELSE Printer.ModelName END
You can't use a CASE statement to define where conditions like that. It will be easier to just use some boolean logic
SELECT *
FROM your_table
WHERE (DATALENGTH(CostRule.ModelName) = 0
AND CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1)
OR (DATALENGTH(CostRule.ModelName) != 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1)
There are some other things that could be removed (like CostRule.ColorType = 1 since it is the same in both branches) but I've left them in here to illustrate how to transform your CASE statement into a boolean logic set.
It looks like you would just need to change the WHERE statement:
It looks like you will just need to change your WHERE statement to use OR and remove the CASE Statement.
(SELECT TOP 1
CostValue
FROM
[~client_table~].[dbo].[CostRules] AS CostRule
WHERE
DATALENGTH(CostRule.ModelName) = 0
CostRule.Type = 1
AND CostRule.Manufacturer = Printer.ManufacturerId
AND CostRule.ColorType = 1
OR
DATALENGTH(CostRule.ModelName) <> 0
AND CostRule.Type = 2
AND CostRule.ModelName = Printer.ModelName
AND CostRule.ColorType = 1
) AS MonoCost

The multi-part identifier "SR_DOC_HDR.DOC_VERS_NO" could not be bound

This is the failed query.
Failed SQL:
Select SO_DOC_CD,
SO_DOC_DEPT_CD,
SO_DOC_ID,
SO_DOC_VERS_NO,
SR_DOC_CD,
SR_DOC_DEPT_CD,
SR_DOC_ID,
SR_DOC_VERS_NO,
DOC_LAST_DT,
DOC_PHASE_CD,
DOC_PHASE_CD_SO,
DOC_STA_CD,
VEND_CUST_CD,
DOC_SH_DSCR,
RESP_STA,
RESP_TM_WEB,
"Created By",
QRY_SRCH_STRING,
SO_DOC_REF,
SR_DOC_REF,
SO_DOC_FUNC_CD,
RESP_DT_ADV,
SO_SR_QRY.RESP_STA_ORD,
APPL_STA_CD,
SO_SR_QRY.APPL_STA_CD_ORD,
SO_SR_QRY.AWD_FL
From (
Select SO_DOC_HDR.DOC_CD As SO_DOC_CD,
SO_DOC_HDR.DOC_DEPT_CD As SO_DOC_DEPT_CD,
SO_DOC_HDR.DOC_ID As SO_DOC_ID,
SO_DOC_HDR.DOC_VERS_NO As SO_DOC_VERS_NO,
SO_DOC_HDR.SO_CLSNG_DT As SO_CLSNG_DT,
SO_DOC_HDR.SO_CLSNG_TM As SO_CLSNG_TM,
SR_DOC_HDR.DOC_CD As SR_DOC_CD,
SR_DOC_HDR.DOC_DEPT_CD As SR_DOC_DEPT_CD,
SR_DOC_HDR.DOC_ID As SR_DOC_ID,
SR_DOC_HDR.DOC_VERS_NO As SR_DOC_VERS_NO,
SR_DOC_HDR.DOC_LAST_DT As DOC_LAST_DT,
SR_DOC_HDR.DOC_PHASE_CD As DOC_PHASE_CD,
SR_DOC_HDR.APPL_STA_CD As APPL_STA_CD,
SO_DOC_HDR.DOC_PHASE_CD As DOC_PHASE_CD_SO,
SR_DOC_HDR.DOC_STA_CD As DOC_STA_CD,
SR_DOC_HDR.VEND_CUST_CD As VEND_CUST_CD,
SO_DOC_HDR.DOC_SH_DSCR As DOC_SH_DSCR,
SR_DOC_HDR.RESP_STA As RESP_STA,
SR_DOC_HDR.RESP_TM_WEB As RESP_TM_WEB,
SR_DOC_HDR.DOC_CREA_USID As "Created By",
SR_DOC_HDR.QRY_SRCH_STRING As QRY_SRCH_STRING,
SO_DOC_HDR.DOC_REF As SO_DOC_REF,
SR_DOC_HDR.DOC_REF As SR_DOC_REF,
SO_DOC_HDR.DOC_FUNC_CD As SO_DOC_FUNC_CD,
SR_DOC_HDR.RESP_DT_ADV As RESP_DT_ADV,
Case When RESP_STA = 7 Then 1
When RESP_STA = 1 Then 2
When RESP_STA = 2 Then 4
When RESP_STA = 3 Then 3
When RESP_STA = 4 Then 5
When RESP_STA = 5 Then 6
End As RESP_STA_ORD,
Case When APPL_STA_CD = 5 Then 1
When APPL_STA_CD = 4 Then 2
When APPL_STA_CD = 1 Then 3
When APPL_STA_CD = 3 Then 4
When APPL_STA_CD = 6 Then 5
When APPL_STA_CD = 2 Then 6
When APPL_STA_CD = 7 Then 7
End As APPL_STA_CD_ORD,
Case When Exists (
Select 1
From SR_DOC_COMMLN
Where SR_DOC_COMMLN.SO_DOC_ID = SR_DOC_HDR.SO_DOC_ID
And SR_DOC_COMMLN.SO_DOC_DEPT_CD = SR_DOC_HDR.SO_DOC_DEPT_CD
And SR_DOC_COMMLN.SO_DOC_VERS_NO = SR_DOC_HDR.SO_DOC_VERS_NO
And SR_DOC_COMMLN.SO_DOC_CD = SR_DOC_HDR.SO_DOC_CD
And (
SR_DOC_COMMLN.AWARD_CREATED = 1
Or SR_DOC_COMMLN.AWARD_FINALIZED = 1
)
) Then 1
Else 0
End As AWD_FL
From av3112jm1.dbo.SR_DOC_HDR SR_DOC_HDR,
av3112jm1.dbo.SO_DOC_HDR SO_DOC_HDR
Where SO_DOC_HDR.DOC_CD = SR_DOC_HDR.SO_DOC_CD
And SO_DOC_HDR.DOC_DEPT_CD = SR_DOC_HDR.SO_DOC_DEPT_CD
And SO_DOC_HDR.DOC_ID = SR_DOC_HDR.SO_DOC_ID
And SO_DOC_HDR.DOC_PHASE_CD = 3
) SO_SR_QRY
Where 1 = 1
And (
SR_DOC_HDR.DOC_VERS_NO = 1
And SR_DOC_HDR.DOC_DEPT_CD = '010'
And SR_DOC_HDR.DOC_CD = 'GFA'
And SR_DOC_HDR.DOC_ID = 'ESR09141700000000002'
)
Order By Case When SO_DOC_FUNC_CD = 3 Then 4
When SO_SR_QRY.AWD_FL = 1 Then 2
When Convert(DateTime, SO_CLSNG_DT, (108)) + Convert(DateTime, SO_CLSNG_TM, 114) <= '2017-09-20 02:44:23' Then 3
Else 1
End Asc,
SO_CLSNG_DT Desc,
SO_CLSNG_TM Desc;
The problem is that in your outer query, you're referencing SR_DOC_HDR.DOC_VERS_NO = 1, but your inner query has that column aliased as SR_DOC_VERS_NO.
You need to use the aliases given in the inner query.
Change your outer WHERE statement to:
Where 1 = 1
And (
SR_DOC_VERS_NO = 1
And SR_DOC_DEPT_CD = '010'
And SR_DOC_CD = 'GFA'
And SR_DOC_ID = 'ESR09141700000000002'
)
in your subquery you use twice the alias
sr_doc_hdr.doc_vers_no AS SR_DOC_VERS_NO

SQL CASE Clauses with variable

I get this error:
Incorrect syntax near '='.
Code:
WHERE
T.[ID] = -9769
AND TNS.Active = 1
AND CASE
WHEN T.[StatusID] IN (1,6)
THEN (T.[AuditUser_ID] = 2 AND TNX.Actor = 2)
END
WHERE
T.[ID] = -9769
AND TNS.Active = 1
AND 1 = CASE
WHEN T.[StatusID] IN (1,6)
and (T.[AuditUser_ID] = 2 AND TNX.Actor = 2) then 1 else 0
END

Error in assigning object of nullable type in vb.net

I am new to VB.net and facing a strange situation. I have a structure that contains another structure. The inner structure is nullable. Now wht I do is something like the following. I create a new instance of the inner structure, set the member variables and assign the whole structure to the inner structure of the parent. But it is giving an error. The assignment is not successful. If I try to peek into the structure in the watch window, it says "property evaluation failed" for the HasValue and Value properties.
Dim testData As List(Of TestData) = Nothing
Dim testData_List1 As New TestData
With testData_List1.commonTestParam
.AccuchekActiveEnergy = 2.56
.AccuchekActiveEnergyUnit = ActiveEnergyUnit.KiloWattHour
.AccuchekApparentEnergy = 34.56
.AccuchekApparentEnergyUnit = ApparentEnergyUnit.VoltAmpereHour
.AccuchekFrequency = 1
.AccuchekRange = "20474 ewr 34324"
.AccuchekType = AccuchekType.AccuchekOne
.ActiveLoadRPhase = 145
.AvgActiveLoad = 2.56
.AvgActiveLoadUnit = ActiveLoadUnit.Watt
.AvgPowerFactor = 0
.AvgPowerFactorType = PowerFactorType.PFLag
.ConditionalFlag1 = 0
.ConsumerNo = "343122050242"
.CurrentRPhase = 1
.GeneralFlag1 = 0
.InstantaneousPFRPhase = 2
.ManufacturingYear = 2009
.MeterActiveEnergy = 258.89
.MeterActiveEnergyUnit = ActiveEnergyUnit.KiloWattHour
.MeterActiveError = 20
.MeterApparentError = 14
.MeterConstant = 3200
.MeterConstantUnit = MeterConstantUnit.RevsPerkVAh
.MeterMake = "DS"
.MeterSNo = "6563402"
.MeterTypeAndClass = MeterTypeAndClass.MTCElectorMechWith20
.MTFID = "123456789"
.NoofTestRevolutions = 100
.PulseCriteria = 0
.RatedBasic = 25
.RatedMax = 30
.RatedVoltage = 15
.ReactiveCurrentRPhase = 145
.RemarkID = 0
.TestDateAndTime = "100320101545"
.TestDuration = 2145
.TesterCode = 0
.TestID = "147852"
.TestMode = TestMode.TMOpticalScanner
.TestNumber = 0
.VoltageRPhase = 145
End With
Dim accuchek3TestParameters1 As New Accuchek3PhaseTestParameters
With accuchek3TestParameters1
.AccuchekReactiveLagEnergy = 2.46
.AccuchekReactiveLagEnergyUnit = ReactiveEnergyUnit.KiloVoltAmpereReactiveHour
.AccuchekReactiveLeadEnergy = 2.56
.AccuchekReactiveLeadEnergyUnit = ReactiveEnergyUnit.KiloVoltAmpereReactiveHour
.ActiveLoadBPhase = 14
.ActiveLoadYPhase = 15
.AvgApparentLoad = 10
.AvgApparentLoadUnit = ApparentLoadUnit.KiloVoltAmpere
.AvgReactiveLagLoad = 14
.AvgReactiveLagLoadUnit = ReactiveLoadUnit.KiloVoltAmpereReactive
.AvgReactiveLeadLoad = 15
.AvgReactiveLeadLoadUnit = ReactiveLoadUnit.KiloVoltAmpereReactive
.ConditionalFlag2 = 0
.ConditionalFlag3 = 0
.CTRatio = 1.23
.CurrentBPhase = 10
.CurrentYPhase = 11
.InstantaneousPFBPhase = 0
.InstantaneousPFYPhase = 1
.MeterApparentEnergy = 1.01
.MeterApparentUnit = ApparentEnergyUnit.KiloVoltAmpereHour
.MeterReactiveLagEnergy = 1.25
.MeterReactiveLagError = 1.25
.MeterReactiveLagUnit = ReactiveEnergyUnit.KiloVoltAmpereReactiveHour
.MeterReactiveLeadEnergy = 1.45
.MeterReactiveLeadError = 1.56
.MeterReactiveLeadUnit = ReactiveEnergyUnit.KiloVoltAmpereReactiveHour
.PercentageLoad = 1
.PTRatio = 1
.ReactiveCurrentBPhase = 10
.ReactiveCurrentYPhase = 11
.VoltageBPhase = 10
.VoltageYPhase = 10
End With
testData_List1.accuchek3TestParameters = accuchek3TestParameters1
testData.Add(testData_List1)
Can somebody please guide me?
Your first line is:
Dim testData As List(Of TestData) = Nothing
Then at the bottom you do
testData.Add(testData_List1)
I can't see anywhere in between where you do something like:
testData = New List(Of TestData)()
Though it's slightly hard to read since you've got both a variables and types with TestData as their name (or part of their name) so I might just be missing that.