Query with many CASE statements - optimization - sql

I have one very dirty query that per sure can be optimized because there are so many CASE statements in it!
SELECT
(CASE pa.KplusTable_Id WHEN 1 THEN sp.sp_id
WHEN 2 THEN fw.fw_id
WHEN 3 THEN s.sw_Id
WHEN 4 THEN id.ia_id END) as Deal_Id,
max(CASE pa.KplusTable_Id WHEN 1 THEN sp.Trans_Id
WHEN 2 THEN fw.Trans_Id
WHEN 3 THEN s.Trans_Id
WHEN 4 THEN id.Trans_Id END) as TransId_CurrentMax
INTO #MaxRazlicitOdNull
FROM #PotencijalniAktuelni pa LEFT JOIN kplus_sp sp (nolock) on sp.sp_id=pa.Deal_Id AND pa.KplusTable_Id=1
LEFT JOIN kplus_fw fw (nolock) on fw.fw_id=pa.Deal_Id AND pa.KplusTable_Id=2
LEFT JOIN dev_sw s (nolock) on s.sw_Id=pa.Deal_Id AND pa.KplusTable_Id=3
LEFT JOIN kplus_ia id (nolock) on id.ia_id=pa.Deal_Id AND pa.KplusTable_Id=4
WHERE isnull(CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END, '')<>''
GROUP BY CASE pa.KplusTable_Id WHEN 1 THEN sp.sp_id
WHEN 2 THEN fw.fw_id
WHEN 3 THEN s.sw_Id
WHEN 4 THEN id.ia_id END
Because I have same condition couple times, do you have idea how to optimize query, make it simpler and better. All suggestions are welcome!
TnX in advance!
Nemanja

To me this looks like a botched attempt in sub-typing. This is what I think you have now.
Based on the model, the following should work:
;
with
q_00 as (
select
pa.Deal_Id as Deal_Id
, coalesce(sp.BROJ_TIKETA, fw.BROJ_TIKETA, sw.tiket, ia.BROJ_TIKETA, '') as Ticket_No
, coalesce(sp.Trans_Id, fw.Trans_Id, sw.Trans_Id, ia.Trans_Id) as Trans_Id
from #PotencijalniAktuelni as pa
left join kplus_sp as sp on sp.sp_Id = pa.Deal_Id and pa.KplusTable_Id = 1
left join kplus_fw as fw on fw.fw_Id = pa.Deal_Id and pa.KplusTable_Id = 2
left join dev_sw as sw on sw.sw_Id = pa.Deal_Id and pa.KplusTable_Id = 3
left join kplus_ia as ia on ia.ia_Id = pa.Deal_Id and pa.KplusTable_Id = 4
)
select
Deal_Id
, max(Trans_Id) as TransId_CurrentMax
into #MaxRazlicitOdNull
from q_00
where Ticket_No <> ''
group by Deal_Id ;
SQL Server 2005 +

The quickest query may be to union each of the 4 clauses out and union them together. The code ends up longer but its much more clear what each block does - especially if you comment them together.
-- When KplusTable_Id = 1
Select
sp.sp_id as as Deal_Id,
max(sp.Trans_Id) as TransId_CurrentMax
FROM #PotencijalniAktuelni pa LEFT JOIN kplus_sp sp (nolock) on sp.sp_id=pa.Deal_Id AND pa.KplusTable_Id=1
LEFT JOIN kplus_fw fw (nolock) on fw.fw_id=pa.Deal_Id AND pa.KplusTable_Id=2
LEFT JOIN dev_sw s (nolock) on s.sw_Id=pa.Deal_Id AND pa.KplusTable_Id=3
LEFT JOIN kplus_ia id (nolock) on id.ia_id=pa.Deal_Id AND pa.KplusTable_Id=4
WHERE sp.BROJ_TIKETA <>''
and pa.KplusTable_Id = 1
GROUP BY sp.sp_id
Union ...
-- When 2
Wrap the entire query in a select to do your insert into #MaxRazlicitOdNull

The Cases is Ok for me. Usually are faster than Union.
Put several variants of your query and compare batch in Plan.
Only one (insignificant) details
Change
WHERE isnull(CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END, '')<>''
for this
WHERE CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END is not null
Another sol (with UNION):
SELECT pa.Deal_Id, MAX(Q.Trans_Id) AS TransId_CurrentMax
INTO #MaxRazlicitOdNull
FROM
(SELECT 1 A KplusTable_Id, Trans_Id, sp_id AS Deal_Id FROM kplus_sp
UNION
SELECT 2 AS KplusTable_Id, Trans_Id, fw_id AS Deal_Id FROM kplus_fw
UNION
SELECT 3 AS KplusTable_Id, Trans_Id, sw_Id AS Deal_Id FROM dev_sw
UNION
SELECT 4 AS KplusTable_Id, Trans_Id, ia_id AS Deal_Id FROM kplus_ia) AS Q
INNER JOIN #PotencijalniAktuelni pa ON pa.KplusTable_Id=Q.KplusTable_Id AND pa.Deal_Id=Q.Deal_Id
GROUP BY pa.Deal_Id
Test every variant of query in plan and choose faster

Related

Left join oracle db

I have two tables and I wanna join them (outer).
day description
-----
1 mo
2 tu
...
5 fr
order day code
----
1 1 0
2 2 0
3 1 2
4 3 0
5 4 0
I wanna this table as a result:
description order code
------
mo 1 0
th 2 0
we 4 0
tu 5 0
fr null null
When I use a left join like this, the code does not work right and does not show me friday:
select *
from days d left join order o on d.id= o.day
where o.code = 0
But when I write the code like this, the code works right:
select *
from
(select * from day) d
left join
(select * from order when code = 0) o
on d.id = o.day
Does anyone know why?
Just put the condition on the left joined table in the on clause of the left join rather than in the where clause:
select d.description, o.order, o.code
from days d
left join order o on d.id= o.day and o.code = 0
Conditions in the where clause are mandatory - so the where clause eliminates rows where the left join came back empty, since o.code is null, which is not equal to 0.
on condition is used to join the table.
where condition is to filter the records from the join result.
Below will join the table on the condition of d.id = o.day
and then select records only with o.code=0
select *
from days d left join order o on d.id= o.day
where o.code = 0
In order to join on both d.id = o.day and o.code=0
you need below
select *
from days d left join order o on d.id= o.day
and o.code = 0

Want to alter multiple pivot result

I am using two pivot operators with union all in my query and I am getting data which I wanted
but I am getting the data from second pivot as new rows but I want these values to come as new columns in the table. I am getting data like this:
Name Ep ER FT SQ
Amir 2 9 3 2
muzamil NULL 5 NULL
roof 2 9 3 7
Amir 0 9 3 1
muzamil NULL 5 NULL
roof 2 7 3 7
First three rows are output of first pivot and last three rows are output of second pivot.But I want values in last three rows come as new columns to the first three rows.
I want data to be output like this:
Name Ep ER FT SQ JB CQ LQ YC
Amir 2 9 3 2 0 9 3 1
muzamil NULL 5 NULL NULL 5 NULL NULL
roof 2 9 3 7 2 7 3 7
with JB CQ LQ YC as new columns from last three rows my pivot query is like this:
Declare #S nvarchar(1024)
Declare #Q nvarchar(Max)
set #S=''
Select #S=#S+a.[Column] +',' from
(SELECT distinct ISNULL( dbo.tbSubjects.SubCode,'NoColumnName') as [Column] FROM dbo.tbAttendance INNER JOIN
dbo.tbAttendanceMaster ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID INNER JOIN
dbo.tbStudent ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID INNER JOIN
dbo.tbSubjects ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID LEFT OUTER JOIN
dbo.tbSemester ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID
) as a
set #S=LEFT(#S,LEN(#S)-1)
print #S
set #Q='select Name,'+#S+' from (SELECT distinct tbStudent.Name, dbo.tbSubjects.SubCode, dbo.fnTotalDays(dbo.tbAttendanceMaster.SubID,
dbo.tbStudent.StudentID) AS Total
FROM dbo.tbAttendance INNER JOIN
dbo.tbAttendanceMaster ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID INNER JOIN
dbo.tbStudent ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID INNER JOIN
dbo.tbSubjects ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID LEFT OUTER JOIN
dbo.tbSemester ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID ) sq
pivot(sum(Total) for SubCode IN('+#S+') ) as pt
union all
'
set #Q=#Q+'select Name,'+#S+' from (SELECT distinct tbStudent.Name, dbo.tbSubjects.SubCode, dbo.fnNoOfDays(dbo.tbAttendanceMaster.SubID, dbo.tbStudent.StudentID) AS Present
FROM dbo.tbAttendance INNER JOIN
dbo.tbAttendanceMaster ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID INNER JOIN
dbo.tbStudent ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID INNER JOIN
dbo.tbSubjects ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID LEFT OUTER JOIN
dbo.tbSemester ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID ) sq2
pivot(sum(Present) for SubCode IN('+#S+') ) as pt2
'
Execute sp_Executesql #Q
print #Q

Wrong output by query in ms sql server

I have written a query in ms sql server in which I am using pivoting. As I am not familiar with pivoting I want to know where I am going wrong, as my query is not producing the desired output. My query is like this:
SELECT Name,ap,er,ft,vp
FROM (SELECT DISTINCT tbStudent.Name,
dbo.tbSubjects.SubCode,
dbo.fnTotalDays(dbo.tbAttendanceMaster.SubID,
dbo.tbStudent.StudentID) AS Total
FROM dbo.tbAttendance
INNER JOIN dbo.tbAttendanceMaster
ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID
INNER JOIN dbo.tbStudent
ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID
INNER JOIN dbo.tbSubjects
ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID
LEFT OUTER JOIN dbo.tbSemester
ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID) sq
PIVOT(sum(Total) FOR SubCode IN(ap,er,ft,vp) ) AS pt
UNION ALL
SELECT Name ,ap ,er ,ft ,vp
FROM (SELECT DISTINCT tbStudent.Name,
dbo.tbSubjects.SubCode,
dbo.fnNoOfDays(dbo.tbAttendanceMaster.SubID,
dbo.tbStudent.StudentID) AS Present
FROM dbo.tbAttendance
INNER JOIN dbo.tbAttendanceMaster
ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID
INNER JOIN dbo.tbStudent
ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID
INNER JOIN dbo.tbSubjects
ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID
LEFT OUTER JOIN dbo.tbSemester
ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID ) sq2
PIVOT(sum(Present) FOR SubCode IN(ap,er,ft,vp) ) AS pt2
It is giving me output like this:
Name Ep ER FT SQ
Amir 2 9 3 2
muzamil NULL 5 NULL
roof 2 9 3 7
Amir 0 9 3 1
muzamil NULL 5 NULL
roof 2 7 3 7
but I want output like this:
Name Ep ER FT SQ JB CQ LQ YC
Amir 2 9 3 2 0 9 3 1
muzamil NULL 5 NULL NULL 5 NULL NULL
roof 2 9 3 7 2 7 3 7
I want the last three rows which are the output of second query to show as the new columns JB, CQ, LQ and YC on the original three rows as shown in my table above.
There seem to be some mismatches in the column names in your query, you use SELECT Name,ap,er,ft,vp but the sample output lists Name Ep ER FT SQ, so you might have to adjust the answer below to fit your needs.
I think this query might work:
SELECT
Name,
MAX(ap) AS EP, MAX(er) AS ER,
MAX(ft) AS FT, MAX(vp) AS SQ,
MAX(jb) AS JB, MAX(cq) AS CQ,
MAX(lq) AS LQ, MAX(yc) AS YC
FROM (
SELECT
Name,
ap, er, ft, vp,
NULL AS JB, NULL AS CQ, NULL AS LQ, NULL AS YC
FROM (
SELECT DISTINCT
tbStudent.Name,
dbo.tbSubjects.SubCode,
dbo.fnTotalDays(dbo.tbAttendanceMaster.SubID,
dbo.tbStudent.StudentID) AS Total
FROM dbo.tbAttendance
INNER JOIN dbo.tbAttendanceMaster
ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID
INNER JOIN dbo.tbStudent
ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID
INNER JOIN dbo.tbSubjects
ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID
LEFT OUTER JOIN dbo.tbSemester
ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID
) sq
PIVOT(SUM(Total) FOR SubCode IN (ap,er,ft,vp)
) AS pt
UNION ALL
SELECT
Name,
NULL AS ap, NULL AS er, NULL AS ft, NULL AS vp,
ap AS JB, er AS CQ, ft AS LQ, vp AS YC
FROM (
SELECT DISTINCT tbStudent.Name,
dbo.tbSubjects.SubCode,
dbo.fnNoOfDays(dbo.tbAttendanceMaster.SubID,
dbo.tbStudent.StudentID) AS Present
FROM dbo.tbAttendance
INNER JOIN dbo.tbAttendanceMaster
ON dbo.tbAttendance.MasterAID = dbo.tbAttendanceMaster.AtdID
INNER JOIN dbo.tbStudent
ON dbo.tbAttendance.StID = dbo.tbStudent.StudentID
INNER JOIN dbo.tbSubjects
ON dbo.tbAttendanceMaster.SubID = dbo.tbSubjects.SubID
LEFT OUTER JOIN dbo.tbSemester
ON dbo.tbSubjects.SemID = dbo.tbSemester.SemID
) sq2
PIVOT(SUM(Present) FOR SubCode IN (ap,er,ft,vp)
) AS pt2
) AS subquery GROUP BY Name

Not able to perform Query Grouping

i want to rotate my table horizontally -
The tables are as follows:
Master_Choicecode
ChoiceCode MainCourseId CourseLevelId InstituteId
Master_MainCourse
MainCourseId MainCourseName CourseLevelId CourseProgram
11 x 1 abc
12 y 2 xyz
Master_CourseLevel
CourseLevelId CourseLevelName
1 deg
2 Dip
Master_Institute
Instituteid InstituteName Statusid
1001 Insti1 100
1002 Insti2 200
Master_InstituteStatus
StatusId StatusName
100 Status1
200 Status2
Now using all these tables i want to show this:
CourseProgram CourseLevelName Status1(from Master_InstituteStatus) Status2(from Master_InstituteStatus)
abc Deg Count of institutes belonging to status1 Count of institutes belonging to status2
Now this is what i have tried:
SELECT B.CourseProgram,C.CourseLevelName,
case when E.InstituteStatusName =' Status1' then COUNT(*) else null end as Status1,
case when E.InstituteStatusName =' Status2' then COUNT(*) else null end as Status2,
FROM Master_ChoiceCode A
inner join Master_MainCourse B on A.MainCourseID=B.MainCourseID
inner join Master_CourseLevel C on A.CourseLevelID=C.CourseLevelID
inner join Master_Institute D on A.InstituteID=D.InstituteID
inner join Master_InstituteStatus1 E on D.InstituteStatusID1=E.InstituteStatusID
where B.CourseLevelID IN(1,2)
GROUP BY B.CourseProgram,A.CourseLevelID,C.CourseLevelName,E.InstituteStatusName
order by B.CourseProgram,C.CourseLevelName;
But with this i get the output like this:
CourseProgram CourseLevelName Status1(from Master_InstituteStatus) Status2(from Master_InstituteStatus)
abc Deg Count of institutes belonging to status1
abc Deg Null Count of institutes belonging to status1
i got the solution to this is to use pivot...but i dont knw how shal i use Pivot with my current query.Please help me..
You're close, but grouping on E.InstituteStatusName means you will not be able to combine the data onto one row. Rather than use the case statement with a count, you could use a conditional sum.
SELECT B.CourseProgram,C.CourseLevelName,
sum(case when E.InstituteStatusName =' Status1' then 1 else 0 end) as Status1,
sum(case when E.InstituteStatusName =' Status2' then 1 else 0 end) as Status2,
FROM Master_ChoiceCode A
inner join Master_MainCourse B on A.MainCourseID=B.MainCourseID
inner join Master_CourseLevel C on A.CourseLevelID=C.CourseLevelID
inner join Master_Institute D on A.InstituteID=D.InstituteID
inner join Master_InstituteStatus1 E on D.InstituteStatusID1=E.InstituteStatusID
where B.CourseLevelID IN(1,2)
GROUP BY B.CourseProgram,A.CourseLevelID,C.CourseLevelName
order by B.CourseProgram,C.CourseLevelName;
This will effectively count the rows matching that status without the need for grouping on that field.
You could use the built in PIVOT function in SQL-Server:
WITH CTE AS
( SELECT B.CourseProgram,
C.CourseLevelName,
E.InstituteStatusName,
b.CourseLevelID
FROM Master_ChoiceCode A
INNER JOIN Master_MainCourse B
ON A.MainCourseID=B.MainCourseID
INNER JOIN Master_CourseLevel C
ON A.CourseLevelID=C.CourseLevelID
INNER JOIN Master_Institute D
ON A.InstituteID=D.InstituteID
INNER JOIN Master_InstituteStatus1 E
ON D.InstituteStatusID1=E.InstituteStatusID
WHERE B.CourseLevelID IN (1,2)
)
SELECT CourseProgram, CourseLevelName, [Status1], [Status2]
FROM CTE
PIVOT
( COUNT(CourseLevelID)
FOR InstituteStatusName IN ([Status1], [Status2])
) pvt
ORDER BY CourseProgram, CourseLevelName;

Query with many CASE statements - optimization [duplicate]

I have one very dirty query that per sure can be optimized because there are so many CASE statements in it!
SELECT
(CASE pa.KplusTable_Id WHEN 1 THEN sp.sp_id
WHEN 2 THEN fw.fw_id
WHEN 3 THEN s.sw_Id
WHEN 4 THEN id.ia_id END) as Deal_Id,
max(CASE pa.KplusTable_Id WHEN 1 THEN sp.Trans_Id
WHEN 2 THEN fw.Trans_Id
WHEN 3 THEN s.Trans_Id
WHEN 4 THEN id.Trans_Id END) as TransId_CurrentMax
INTO #MaxRazlicitOdNull
FROM #PotencijalniAktuelni pa LEFT JOIN kplus_sp sp (nolock) on sp.sp_id=pa.Deal_Id AND pa.KplusTable_Id=1
LEFT JOIN kplus_fw fw (nolock) on fw.fw_id=pa.Deal_Id AND pa.KplusTable_Id=2
LEFT JOIN dev_sw s (nolock) on s.sw_Id=pa.Deal_Id AND pa.KplusTable_Id=3
LEFT JOIN kplus_ia id (nolock) on id.ia_id=pa.Deal_Id AND pa.KplusTable_Id=4
WHERE isnull(CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END, '')<>''
GROUP BY CASE pa.KplusTable_Id WHEN 1 THEN sp.sp_id
WHEN 2 THEN fw.fw_id
WHEN 3 THEN s.sw_Id
WHEN 4 THEN id.ia_id END
Because I have same condition couple times, do you have idea how to optimize query, make it simpler and better. All suggestions are welcome!
TnX in advance!
Nemanja
To me this looks like a botched attempt in sub-typing. This is what I think you have now.
Based on the model, the following should work:
;
with
q_00 as (
select
pa.Deal_Id as Deal_Id
, coalesce(sp.BROJ_TIKETA, fw.BROJ_TIKETA, sw.tiket, ia.BROJ_TIKETA, '') as Ticket_No
, coalesce(sp.Trans_Id, fw.Trans_Id, sw.Trans_Id, ia.Trans_Id) as Trans_Id
from #PotencijalniAktuelni as pa
left join kplus_sp as sp on sp.sp_Id = pa.Deal_Id and pa.KplusTable_Id = 1
left join kplus_fw as fw on fw.fw_Id = pa.Deal_Id and pa.KplusTable_Id = 2
left join dev_sw as sw on sw.sw_Id = pa.Deal_Id and pa.KplusTable_Id = 3
left join kplus_ia as ia on ia.ia_Id = pa.Deal_Id and pa.KplusTable_Id = 4
)
select
Deal_Id
, max(Trans_Id) as TransId_CurrentMax
into #MaxRazlicitOdNull
from q_00
where Ticket_No <> ''
group by Deal_Id ;
SQL Server 2005 +
The quickest query may be to union each of the 4 clauses out and union them together. The code ends up longer but its much more clear what each block does - especially if you comment them together.
-- When KplusTable_Id = 1
Select
sp.sp_id as as Deal_Id,
max(sp.Trans_Id) as TransId_CurrentMax
FROM #PotencijalniAktuelni pa LEFT JOIN kplus_sp sp (nolock) on sp.sp_id=pa.Deal_Id AND pa.KplusTable_Id=1
LEFT JOIN kplus_fw fw (nolock) on fw.fw_id=pa.Deal_Id AND pa.KplusTable_Id=2
LEFT JOIN dev_sw s (nolock) on s.sw_Id=pa.Deal_Id AND pa.KplusTable_Id=3
LEFT JOIN kplus_ia id (nolock) on id.ia_id=pa.Deal_Id AND pa.KplusTable_Id=4
WHERE sp.BROJ_TIKETA <>''
and pa.KplusTable_Id = 1
GROUP BY sp.sp_id
Union ...
-- When 2
Wrap the entire query in a select to do your insert into #MaxRazlicitOdNull
The Cases is Ok for me. Usually are faster than Union.
Put several variants of your query and compare batch in Plan.
Only one (insignificant) details
Change
WHERE isnull(CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END, '')<>''
for this
WHERE CASE pa.KplusTable_Id WHEN 1 THEN sp.BROJ_TIKETA
WHEN 2 THEN fw.BROJ_TIKETA
WHEN 3 THEN s.tiket
WHEN 4 THEN id.BROJ_TIKETA END is not null
Another sol (with UNION):
SELECT pa.Deal_Id, MAX(Q.Trans_Id) AS TransId_CurrentMax
INTO #MaxRazlicitOdNull
FROM
(SELECT 1 A KplusTable_Id, Trans_Id, sp_id AS Deal_Id FROM kplus_sp
UNION
SELECT 2 AS KplusTable_Id, Trans_Id, fw_id AS Deal_Id FROM kplus_fw
UNION
SELECT 3 AS KplusTable_Id, Trans_Id, sw_Id AS Deal_Id FROM dev_sw
UNION
SELECT 4 AS KplusTable_Id, Trans_Id, ia_id AS Deal_Id FROM kplus_ia) AS Q
INNER JOIN #PotencijalniAktuelni pa ON pa.KplusTable_Id=Q.KplusTable_Id AND pa.Deal_Id=Q.Deal_Id
GROUP BY pa.Deal_Id
Test every variant of query in plan and choose faster