SQL avoid 0 in the calculation - sql

Can anyone help me try to solve this equation? The "Lost_Weight" is a calculation field and I'm trying to get the result of HWeight - renWeight = '0' if the renWeight is 0. The where clause has a controversial statement that put a Challenge to me to make that happen. See below.
SELECT TOP (100) PERCENT dbo.Name.ID,
dbo.Name.CO_ID,
dbo.Name.FULL_NAME,
dbo.Name.STATE_PROVINCE, dbo.Tops_Profile.START_WGHT,
dbo.Tops_Profile.RENEWAL_WEIGHT,
dbo.Tops_Profile.H_WEIGHT - dbo.Tops_Profile.RENEWAL_WEIGHT AS Lost_Weight,
dbo.Tops_Profile.H_WEIGHT,
dbo.Name.JOIN_DATE,
dbo.Name.BIRTH_DATE,
RIGHT(dbo.TOPS_AWARDS.AWARD_TYPE, 15) AS AWARDS_TYPE,
dbo.TOPS_AWARDS.AWARD_CATEGORY,
dbo.TOPS_AWARDS.AWARD_DATE,
dbo.vw_RegDirs.TARGET_ID AS
RD_ID,
dbo.vw_Coords.TARGET_ID AS Coord_ID,
dbo.vw_Coords.FULL_NAME AS
Coord_Name,
dbo.vw_AreaCapts.TARGET_ID AS AC_ID, dbo.Name.STATUS
FROM dbo.Name INNER JOIN dbo.Tops_Profile
ON dbo.Name.ID = dbo.Tops_Profile.ID
INNER JOIN dbo.vw_RegDirs
ON dbo.Name.CO_ID = dbo.vw_RegDirs.CHAPTER
INNER JOIN dbo.vw_Coords
ON dbo.Name.CO_ID = dbo.vw_Coords.CHAPTER
INNER JOIN dbo.vw_AreaCapts
ON dbo.Name.CO_ID = dbo.vw_AreaCapts.CHAPTER
LEFT OUTER JOIN dbo.TOPS_AWARDS
ON dbo.Name.ID = dbo.TOPS_AWARDS.ID
WHERE (dbo.Tops_Profile.RENEWAL_WEIGHT <> '0')
AND (dbo.Name.STATUS = 'a')
AND (dbo.Tops_Profile.H_WEIGHT - dbo.Tops_Profile.RENEWAL_WEIGHT >= 100')
OR (dbo.Name.STATUS = 'a') AND (dbo.TOPS_AWARDS.AWARD_TYPE LIKE '%Century%')
right now if the renewal_weight is 0 it automatically give me the number from the H_WEIGHT in the Lost_Weight field and I need the result to be 0 if the RENEWAL_WEIGHT is 0.

I'm guessing 0 is a special value in this situation. This can be fixed by using CASE
Replace
dbo.Tops_Profile.H_WEIGHT - dbo.Tops_Profile.RENEWAL_WEIGHT AS Lost_Weight
With
CASE WHEN RENEWAL_WEIGHT = 0 THEN 0
ELSE dbo.Tops_Profile.H_WEIGHT - dbo.Tops_Profile.RENEWAL_WEIGHT
END AS Lost_Weight

Related

Conditionally adding a column in a SQL query

I'm trying to add a conditional SELECT column in a query and I'm having trouble writing it out:
SELECT v.GLTypeID,
v.something,
v.somethignElse,
CASE WHEN (SELECT TOP 1 Value FROM InterfaceParam WHERE InterfaceId = 0 AND Descr = 'gf') = 1 THEN a.CreditID ELSE NULL END AS CreditMemoID
FROM vGLDetails2 v
....
LEFT OUTER JOIN AssociationFund f
ON v.FundID = f.FundID
LEFT JOIN dbo.APLedger a ON v.RelID = a.APLedgerID AND v.RelTypeID IN (39, 40)
....
ORDER BY v.Code;
The query above works, however if the CASE statement is still returning an additional column regardless of the result of the subquery. How can I remove it if the subquery doesn't return a row?
How can I do this?
Change the location of AS. For example:
SELECT v.GLTypeID,
v.something,
v.somethignElse,
CASE WHEN (
SELECT TOP 1 Value
FROM InterfaceParam
WHERE InterfaceId = 0 AND Descr = 'creditMemo') = 1
THEN a.CreditID -- AS is not valid here
END AS CreditMemoID -- AS is valid here
FROM vGLDetails2 v
....
LEFT OUTER JOIN AssociationFund f
ON v.FundID = f.FundID
LEFT JOIN dbo.APLedger a ON v.RelID = a.APLedgerID AND v.RelTypeID IN (39, 40)
....
ORDER BY v.Code;
Note: I removed ELSE NULL since this is the default behavior of CASE.

WHERE Statement - Multiple conditions - adding 2 more

I can't quite get my conditions correct to alter an existing query that works.
SELECT dd.GasYear,D.DealCash_IsAgency,D.DealCash_IsNetBack, dd.GasYearName,dd.MonthName,dd.Season,dd.FirstOfMonthDate,Deal_OrigDate,DATENAME(WEEKDAY, Deal_OrigDate) AS Orig_DayofWeek
,Deal_StartDate,DATENAME(WEEKDAY, Deal_StartDate) AS Start_DayofWeek,Deal_StopDate,DATENAME(WEEKDAY, Deal_StopDate) AS Stop_DayofWeek
,CASE
WHEN CAST(DATEDIFF(d, Deal_StartDate, Deal_StopDate) AS CHAR(10)) > 6 THEN 'All Other'
END AS DealType
,Deal_Owner,d.Deal_Id,CP_Cmp_ShortName
,CASE
WHEN Qty_MeasurementType_Short = 'GJ' THEN DealCashTran_Qty / 2.055098
ELSE DealCashTran_Qty
END DealCashTran_Dth_Qty
FROM uvDealCash d
LEFT OUTER JOIN uvDealCashTran AS dct
ON d.Deal_Id = dct.Deal_Id
INNER JOIN Cmp c
ON d.CP_Cmp_ShortName = c.Cmp_ShortName
INNER JOIN [uvCmp_CmpType_CmpCPType] ct
ON c.Cmp_Id = ct.Cmp_Id
INNER JOIN BISandbox.dbo.dimDate dd
ON d.Deal_StartDate = dd.FullDate
WHERE ((Deal_Owner IN ('TYK', 'JTT', 'MML', 'CGG', 'LIO', 'MAT')
AND ct.CmpCPType_Descript = 'Producer')
--US Entities Kristen's wants added
OR (CP_Cmp_ShortName IN ('SEV', 'CNAT', 'TNMKT', 'CENT')))
AND Deal_LengthInMonths >= 0
AND DATEDIFF(d, Deal_StartDate, Deal_StopDate) > 6
AND Deal_StartDate > '4/1/2018' --=<Parameters.StartDate>
AND DealPurchaseSellType_Short = 'P'
AND d.DealCashType_Short IN ('DFM', 'FM')
In addition to the above I want to exclude results if DealCash_IsAgency = 1 or D.DealCash_IsNetBack = 1
I tried several variations by adding this to the end of the existing WHERE statement.
--exclude AMA and NB
AND (D.DealCash_IsAgency = 1 OR D.DealCash_IsNetBack = 1)
It still returns rows with 1's in both of the columns.
Greatly appreciate any suggestions.
Thanks
Brent
if you want to exclude then you have to add a condition like this by adding not:
AND NOT (D.DealCash_IsAgency = 1 OR D.DealCash_IsNetBack = 1)

SQL query case when then in where clause

I read a lot of similar questions but didn't find a solution for me. Basically I would like to have a where clause (AND PEKP.VORGANGS_ART = 'BE') only if a special condition (PFSP.EINKAUFS_KZ = 2) is true.
I tried in many ways like that:
SELECT *
FROM PFSP
LEFT OUTER JOIN PFAK on PFSP.RUECKMELDE_NR = PFAK.RUECKMELDE_NR
LEFT OUTER JOIN PEKP ON (PFSP.BESTELL_NR=PEKP.VORGANGS_NR)
AND (PFSP.BESTELL_POS_NR=PEKP.VORGANGS_POS_NR)
LEFT OUTER JOIN PMLB ON PFSP.KOMPONENTEN_ARTIKEL_NR=PMLB.ARTIKEL_NR
WHERE PFAK.KD_VORGANGS_NR = '910-001213'
AND PFSP.RUECKMELDE_STATUS = '3'
AND PFSP.BESCHAFFUNGSKENNER = 'F'
AND CASE PFSP.EINKAUFS_KZ
WHEN 2 THEN PEKP.VORGANGS_ART = 'BE'
END
but I keep getting errors:
wrong syntax near '='"
Skip the CASE, use AND/OR instead:
AND (PFSP.EINKAUFS_KZ <> 2 OR PEKP.VORGANGS_ART = 'BE')
If PFSP.EINKAUFS_KZ = 2, then PEKP.VORGANGS_ART must be equal to 'BE'.
If PFSP.EINKAUFS_KZ <> 2, it doesn't matter what PEKP.VORGANGS_ART is.
With this CASE expression:
AND 1 = CASE
WHEN PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART = 'BE' THEN 1
WHEN PFSP.EINKAUFS_KZ = 2 THEN 0
ELSE 1
END
The order of the conditions is important.
You probably want something like:
AND (
(PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART='BE')
OR PFSP.EINKAUFS_KZ <> 2 --You may need to catch NULL as well
)
SELECT *
FROM PFSP
LEFT OUTER JOIN PFAK on PFSP.RUECKMELDE_NR = PFAK.RUECKMELDE_NR
LEFT OUTER JOIN PEKP ON (PFSP.BESTELL_NR=PEKP.VORGANGS_NR)
AND (PFSP.BESTELL_POS_NR=PEKP.VORGANGS_POS_NR)
LEFT OUTER JOIN PMLB ON PFSP.KOMPONENTEN_ARTIKEL_NR=PMLB.ARTIKEL_NR
WHERE PFAK.KD_VORGANGS_NR = '910-001213'
AND PFSP.RUECKMELDE_STATUS = '3'
AND PFSP.BESCHAFFUNGSKENNER = 'F'
AND ((PFSP.EINKAUFS_KZ = 2 AND PEKP.VORGANGS_ART = 'BE') OR (PFSP.EINKAUFS_KZ <> 2) )

Sql in sql server with convert

I am trying to use convert in an where clause in the select statement. My query looks like this:
SELECT DISTINCT TOP 10 [SurveyResult].*
,[Ticket].[RefNumber]
FROM [SurveyResult]
LEFT JOIN [Ticket] ON [SurveyResult].[TicketID] = [Ticket].[TicketID]
JOIN [SurveyResponse] AS SurveyResponse1 ON [SurveyResult].[ResultID] = SurveyResponse1.[ResultID]
JOIN [QuestionAnswer] AS QuestionAnswer1 ON SurveyResponse1.[AnswerID] = QuestionAnswer1.[AnswerID]
JOIN [SurveyQuestion] AS SurveyQuestion1 ON QuestionAnswer1.[QuestionID] = SurveyQuestion1.[QuestionID]
WHERE SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CONVERT(INT, SurveyResponse1.[Response]) >= 1
AND CONVERT(INT, SurveyResponse1.[Response]) <= 5
The problem is that I get some errors when converting the values to integer in the where statement.
I know I have some rows that don't contain numbers in the Response column but I filter those so without the convert part in the where clause I get only numbers so it works like this:
SELECT TOP 1000 [ResponseID]
,[ResultID]
,[Response]
FROM [WFSupport].[dbo].[SurveyResponse]
JOIN QuestionAnswer ON SurveyResponse.AnswerID = QuestionAnswer.AnswerID
WHERE QuestionAnswer.QuestionID = 'C10BF42E-5D51-46BC-AD89-E57BA80EECFD'
And in the results I get numbers but once I add the convert part in the statement I I get an error that it can't convert some text to numbers.
Either do like Mark says or just have NULL values default to something numerical, this would give you a where statement like:
WHERE SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CONVERT(INT, ISNULL(SurveyResponse1.[Response],0)) BETWEEN 1 AND 5
The important part is the ISNULL() function and I also used BETWEEN to avoid duplicate converts.
Try:
SELECT DISTINCT TOP 10
[SurveyResult].*,
[Ticket].[RefNumber]
FROM
[SurveyResult]
LEFT JOIN [Ticket] ON [SurveyResult].[TicketID] = [Ticket].[TicketID]
JOIN [SurveyResponse] AS SurveyResponse1
ON [SurveyResult].[ResultID] = SurveyResponse1.[ResultID]
JOIN [QuestionAnswer] AS QuestionAnswer1
ON SurveyResponse1.[AnswerID] = QuestionAnswer1.[AnswerID]
JOIN [SurveyQuestion] AS SurveyQuestion1
ON QuestionAnswer1.[QuestionID] = SurveyQuestion1.[QuestionID]
where SurveyQuestion1.[SurveyID] = [SurveyResult].[SurveyID]
AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CASE SurveyQuestion1.[QuestionID]
WHEN 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
THEN Convert(int, SurveyResponse1.[Response])
ELSE 0
END BETWEEN 1 AND 5
(The AND SurveyQuestion1.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016' is retained in case the query is using an index on QuestionID - if not, it can be removed, as the same condition is implicit in the subsequent CASE condition.)
Try this one -
SELECT DISTINCT TOP 10 sr.*, t.[RefNumber]
FROM dbo.SurveyResult sr
JOIN dbo.SurveyResponse sr2 ON sr.[ResultID] = sr2.[ResultID]
JOIN dbo.QuestionAnswer sa ON sr2.[AnswerID] = sa.[AnswerID]
JOIN dbo.SurveyQuestion sq ON sa.[QuestionID] = sq.[QuestionID] AND sq.[SurveyID] = sr.[SurveyID]
LEFT JOIN dbo.Ticket t ON sr.[TicketID] = t.[TicketID]
WHERE sq.[QuestionID] = 'C86CB39A-8FE0-4FE8-B38F-17F1BE611016'
AND CAST(ISNULL(sr2.[Response], 0) AS INT) BETWEEN 1 AND 5

Multiple values in SQL CASE's THEN Statement

I am wondering if it is possible to specify multiple values in the then part of a case statement in T-SQL?
I have attached a chunk of code where I am using this to join in some tables in a query. I have included a comment in the snippet.
LEFT JOIN Business B ON v.BusID = B.BusID
LEFT JOIN BusinessTypeKey T ON B.BusinessTypeID = T.BusTypeID
LEFT JOIN Location L ON L.BusID = B.BusID
AND L.HeadQuarters = CASE
WHEN (SELECT COUNT(1) from Location L2
WHERE L2.BusID = B.BusID) = 1
THEN 1,0 -- Would like to specify either 1 or 0 here. I suppose I could also make it euqal to -> L.HeadQuarters but would like a better way to impose it
ELSE 1
END
This is a little ugly, but assuming HeadQuarters is not a decimal/numeric type and only integer values,
AND L.HeadQuarters BETWEEN CASE WHEN (SELECT COUNT...) = 1 THEN 0 ELSE 1 END AND 1;
You mean...?
LEFT JOIN whatever
ON...
CASE...WHEN...THEN...END = 1
OR
CASE...WHEN...THEN...END = 0