Join tables and groupby results based on user defined parameters in sql server 2008 - sql

I want to join two tables and group by the result based on a user defined parameter in Sql Server 2008. I tried the query below but it is not working. I appreciate if someone helps me to see my mistake and correct it for me. Regards.
Select TotalVolume= SUM(volume),
PrimGroup = r.PrimaryGroup, SnGroup = r.SecondaryGroup
from Requests r
inner join #Calculations c on
case #PrimaryId is not null then c.PrimaryGroup = r.PrimaryGroup end
and case #SecondaryId is not null then c.SecondaryGroup = r.SecondaryGroup end
and c.SrgId = r.SrgId
group by
case #PrimaryId is not null then r.PrimaryGroup end,
case #SecondaryId is not null then r.SecondaryGroup end

Try this:
Select TotalVolume= SUM(volume),
PrimGroup = r.PrimaryGroup, SnGroup = r.SecondaryGroup
from Requests r
inner join #Calculations c on
((#PrimaryId is null) or
(#PrimaryId is not null) and c.PrimaryGroup = r.PrimaryGroup)
and ((#SecondaryId is null) or
(#SecondaryId is not null) and c.SecondaryGroup = r.SecondaryGroup)
and c.SrgId = r.SrgId
group by
case when #PrimaryId is not null then r.PrimaryGroup end,
case when #SecondaryId is not null then r.SecondaryGroup end

Related

How to use IF ELSE in JOIN condition (SQL)

I have given the pseudo code below for JOIN condition. Please can you help me on how to write the SQL.
IF (left.detail_valid_to_date = NULL)
WHERE left.right_address_entry_id = right.address_entry_id AND
right.detail_valid_to_date = NULL
IF (left.detail_valid_to_date <> NULL)
WHERE left.right_address_entry_id = right.address_entry_id
AND right.detail_valid_from_date <= left.detail_valid_to_date
AND left.detail_valid_to_date <= right.detail_valid_to_date
select * from
lefttable l inner join righttable r
on l.right_address_entry_id = r.address_entry_id
where (l.detail_valid_to_date = NULL and r.detail_valid_to_date = NULL)
or (l.detail_valid_to_date <> NULL and r.detail_valid_from_date <= l.detail_valid_to_date AND l.detail_valid_to_date <= r.detail_valid_to_date)
I cant really test this without an example but I think since you are doing the same join in either case. You can combine your if statements into a single WHERE clause like so.
FROM right
JOIN left ON left.right_address_entry_id = right.address_entry_id
WHERE (left.detail_valid_to_date is null
and right.detail_valid_to_date is null) or (left.detail_valid_to_date <> NULL
and right.detail_valid_from_date <= left.detail_valid_to_date
and left.detail_valid_to_date <= right.detail_valid_to_date)

Case in update statement

I am trying to translate a talend code which has a nested IF statement into SQL
I thought I had translated it correctly, but no records are getting updated since the join condition fails. I added a top level case statement to check for existence of records, but wanted to double check from the experts here if my translation is correct at all.
Logic from Talend Mapper:
IF row32.DISPLAY_NAME_REPORTED IS NULL THEN
IF row31.REPORTED_DISPLAY_NAME IS NULL THEN
IF row87.SPEC_TYPE1 IS NULL THEN
IF row87.SPEC_TYPE2 IS null THEN
row34.Series
ELSE
row34.Series + row34.Type2
END
ELSE
row34.Series + row34.Type2
END
ELSE
row31.REPORTED_DISPLAY_NAME
END
ELSE
row32.DISPLAY_NAME_REPORTED
END
Corresponding case statement in SQL:
update a
set a.seriesbt = case when exists (select 1 from row32 x where
x.delivery_fk = a.delivery_fk) then
case when b.delivery_fk is not null and
b.DISPLAY_NAME_REPORTED is null then
case when c.reported_display_name is null then
case when d.SPEC_TYPE1 is null then
case when d.SPEC_TYPE2 is null then
a.series
else
a.series+a.SPEC_TYPE2 end
else a.series + a.SPEC_TYPE1 end
else c.reported_display_name end
else b.DISPLAY_NAME_REPORTED end
else a.series end
from tmpSales a
left join row32 b on b.delivery_fk = a.delivery_fk
left join row31 c on c.DELIVERY_FK = a.delivery_fk
left join row87 d on d.DELIVERY_FK = a.delivery_fk
Question is: Did I translate the talend mapper logic into SQL correctly? If not, can you please tell me what is wrong.
Should I be include "when exists" for each table?
I thought the left join should implicitly handle it.
You seem to have added an additional condition that was not in your original code. Coding the opposite way can make things simpler and avoid nested CASE expressions.
I changed your table alias to make it easier to understand where the columns come from without having to go back to the FROM clause.
UPDATE s
SET a.seriesbt = CASE WHEN r32.DISPLAY_NAME_REPORTED IS NOT NULL THEN r32.DISPLAY_NAME_REPORTED
WHEN r31.reported_display_name IS NOT NULL THEN r31.reported_display_name
WHEN r87.SPEC_TYPE1 IS NOT NULL THEN s.series /*row34.Series*/ + s.SPEC_TYPE1
WHEN r87.SPEC_TYPE2 IS NULL THEN s.series --row34.Series
ELSE s.series /*row34.Series*/ + s.SPEC_TYPE2
END
FROM tmpSales s
LEFT JOIN row32 r32 ON r32.delivery_fk = s.delivery_fk
LEFT JOIN row31 r31 ON r31.DELIVERY_FK = s.delivery_fk
LEFT JOIN row87 r87 ON r87.DELIVERY_FK = s.delivery_fk;
I just realized that it could be simplified even more.
UPDATE s
SET a.seriesbt = COALESCE( r32.DISPLAY_NAME_REPORTED,
r31.reported_display_name,
s.series /*row34.Series*/ + s.SPEC_TYPE1,
s.series /*row34.Series*/ + s.SPEC_TYPE2,
s.series --row34.Series
)
FROM tmpSales s
LEFT JOIN row32 r32 ON r32.delivery_fk = s.delivery_fk
LEFT JOIN row31 r31 ON r31.DELIVERY_FK = s.delivery_fk
LEFT JOIN row87 r87 ON r87.DELIVERY_FK = s.delivery_fk;

How to use a non-existing column in sql query

I am working in SQL server 2012. I have to write a sql statement where I first assign a value to [Pay_Type], which is a non-existing column (not sure whether it can be called as variable or not) and based upon its value I want to use it in another case statement as shown below
SELECT sp.First_Name, [Pay_Type] = CASE WHEN NOT EXISTS(SELECT '1' FROM
PERSON_SALARY ps WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL)
THEN 'Hourly' ELSE 'Salary' END,
HOURLY_RATE = CASE WHEN [Pay_Type] = 'Hourly' THEN pj.HOURLY_RATE ELSE
'0.00' END
FROM SEC_PERSON sp
LEFT OUTER JOIN PERSON_JOB pj ON sp.PERSON_ID = pj.PERSON_ID
WHERE sp.END_DATE IS NOT NULL
But I am getting "Invalid column name 'Pay_Type' " error.
Column aliases cannot be re-used in the same SELECT where they are define. The typical answer is to use a subquery or CTE. I also like using a lateral join:
SELECT sp.First_Name, s.Pay_Type,
HOURLY_RATE = (CASE WHEN s.Pay_Type = 'Hourly' THEN pj.HOURLY_RATE ELSE
'0.00' END)
FROM SEC_PERSON sp LEFT OUTER JOIN
PERSON_JOB pj
ON sp.PERSON_ID = pj.PERSON_ID OUTER APPLY
(SELECT (CASE WHEN NOT EXISTS (SELECT 1
FROM PERSON_SALARY ps
WHERE ps.PARTY_ID = sp.PARTY_ID and ps.END_DATE IS NULL
)
THEN 'Hourly' ELSE 'Salary'
END) as PayType
) s
WHERE sp.END_DATE IS NOT NULL

SQL Case statement how to get value regardless of other results

Here is my statement:
SELECT
CASE
WHEN #UserRole = 1 THEN 1
ELSE 0
END AS [CanEdit],
F.FundingStreamName
FROM FundingStream AS F
LEFT JOIN Projects AS P ON P.FundingStream = F.FundingStreamID
WHERE ProjectNumber = #ProjectNumber
I noticed if FundingStreamID is null, the case statement will return nothing as well, how can I get the case statement to execute regardless if there is a funding stream or not? Thanks.
I think the problem is that your where clause is "undoing" your left outer join. Try moving the condition to the on clause:
SELECT (CASE WHEN #UserRole = 1 THEN 1
ELSE 0
END) AS [CanEdit],
F.FundingStreamName
FROM FundingStream F LEFT JOIN
Projects P
ON P.FundingStream = F.FundingStreamID AND
P.ProjectNumber = #ProjectNumber ;
Using #MicSim answer:
SELECT
CASE
WHEN #UserRole = 1 THEN 1
ELSE 0
END AS [CanEdit],
F.FundingStreamName
FROM FundingStream AS F
RIGHT JOIN Projects AS P ON P.FundingStream = F.FundingStreamID
WHERE ProjectNumber = #ProjectNumber
Thanks again for the help!

Stored procedure: how can I set a field value in the returned data without changing the tables it came from?

SELECT
EQ.EventQuestId,
EQ.QuestionText,
EQ.HelpText,
EQ.EventQuestOptType,
EQ.DisplayOrder AS QuestDisplayOrder,
EQO.EventQuestOptId,
EQO.OptionText,
EQO.IsOtherSpecify,
STJC.STJCategory,
EQO.DisplayOrder AS OptDisplayOrder,
EA.EventId, EA.AnswerText
FROM EventQuest EQ
INNER JOIN EventQuestOpt EQO
ON EQ.EventQuestId = EQO.EventQuestId
LEFT JOIN EventAnswer EA
ON EA.EventQuestId = EQ.EventQuestId
AND EA.EventQuestOptId = EQO.EventQuestOptId
AND EventId = #EventId
LEFT JOIN dbo.STJCategories STJC
ON STJC.STJID = EQO.STJID
WHERE EQO.Status <> 'false'
ORDER BY EQ.DisplayOrder, EQO.DisplayOrder
I have this in my stored proc. I want to set the EQ.QuestionText to the STJC.STJCategory value wherever EQ.QuestionText = "example". I just want this in the returned result, not in table it came from. How do I go about this as I've never tried to do this before and have no clue where to begin with that, if it's possible.
I hope this makes sense.
You can use case for that:
select case
when EQ.QuestionText = 'example' then STJC.STJCategory
else EQ.QuestionText
end as QuestionText
use a CASE statement
SELECT
EQ.EventQuestId,
CASE EQ.QuestionText WHEN 'example'
THEN STJC.STJCategory ELSE EQ.QuestionText END QuestionText ,
EQ.HelpText,
EQ.EventQuestOptType,
EQ.DisplayOrder AS QuestDisplayOrder,
EQO.EventQuestOptId,
EQO.OptionText,
EQO.IsOtherSpecify,
STJC.STJCategory,
EQO.DisplayOrder AS OptDisplayOrder,
EA.EventId, EA.AnswerText
FROM EventQuest EQ
INNER JOIN EventQuestOpt EQO
ON EQ.EventQuestId = EQO.EventQuestId
LEFT JOIN EventAnswer EA
ON EA.EventQuestId = EQ.EventQuestId
AND EA.EventQuestOptId = EQO.EventQuestOptId
AND EventId = #EventId
LEFT JOIN dbo.STJCategories STJC
ON STJC.STJID = EQO.STJID
WHERE EQO.Status <> 'false'
ORDER BY EQ.DisplayOrder, EQO.DisplayOrder