The first piece of code represents a update statement that updates all existing columns rows to whatever the user wants. So then i wrote a select statement that grabbed all the columns that were null/not existing and it returns 63 rows without the end where statement but with it then returns 62 which are the ones that are NULL not existing. So now I need to convert the sql select that selects all NUll rows into a insert than puts data into those not existing records. so far I posted what i have. Why isn't this working? it is saying that column schoolDay does not exist, how do i input those fields?
update e
set e.type = #dayEvent
from odb.dayEvent e
inner join odb.day d on e.dayID = d.dayID
inner join MMSD.vSchoolFromCalendar c on d.calendarID = c.calendarID
and d.structureID = c.structureID
inner join odb.PeriodSchedule p on d.periodScheduleID = p.periodScheduleID
and d.structureID = p.structureID
where d.[date] between #toDate and #fromDate
and datepart(dw, d.[date]) not in (1,7)
and e.[type] != #dayEvent
and DistrictCode = 'MA'
and FiscalYear = #FiscalYear
and summerSchool = '0'
and left(SchoolCode, 1) = #schoolChoice
and e.[type] != #dayEvent
select
sts = 'success',
result = convert(varchar, ##rowcount) + ' rows updated.';
set #rowcount = (select ##rowcount);
select
d.schoolDay,
d.instruction,
d.attendance,
d.duration,
d.comments,
d.startTime, d.endTime,
e.type
from
odb.dayEvent e
right outer join
odb.day d on e.dayID = d.dayID
inner join
MMSD.vSchoolFromCalendar c on d.calendarID = c.calendarID
and d.structureID = c.structureID
inner join
odb.PeriodSchedule p on d.periodScheduleID = p.periodScheduleID
and d.structureID = p.structureID
where
d.[date] between '2019-02-12' and '2019-02-12'
and datepart(dw, d.[date]) not in (1, 7)
and DistrictCode = 'MA'
and FiscalYear = '2019'
and summerSchool = '0'
and left(SchoolCode, 1) = '0'
and e.dayEventID IS NULL
Code so far
INSERT INTO odb.dayEvent (schoolDay, instruction, attendance, duration, comments, startTime, endTime)
SELECT
d.schoolDay, d.instruction, d.attendance, d.duration, d.comments,
d.startTime, d.endTime
FROM
odb.dayEvent e
RIGHT OUTER JOIN
odb.day d ON e.dayID = d.dayID
INNER JOIN
MMSD.vSchoolFromCalendar c ON d.calendarID = c.calendarID
AND d.structureID = c.structureID
INNER JOIN
odb.PeriodSchedule p ON d.periodScheduleID = p.periodScheduleID
AND d.structureID = p.structureID
WHERE
d.[date] BETWEEN '2019-02-12' AND '2019-02-12'
AND DATEPART(dw, d.[date]) NOT IN (1, 7)
AND DistrictCode = 'MA'
AND FiscalYear = '2019'
AND summerSchool = '0'
AND LEFT(SchoolCode, 1) = '0'
AND e.dayEventID IS NULL
This is my answer for now, looks like another peace of my code was already solving my questioning issue.....
insert into odb.DayEvent
(dayID, type, duration, instructionalMinutes)
select
e.dayID, e.type, e.duration, e.instructionalMinutes
from odb.dayEvent e
RIGHT OUTER JOIN odb.day d ON e.dayID = d.dayID
INNER JOIN MMSD.vSchoolFromCalendar c ON d.calendarID = c.calendarID
and d.structureID = c.structureID
INNER JOIN odb.PeriodSchedule p ON d.periodScheduleID = p.periodScheduleID
and d.structureID = p.structureID
WHERE d.[date] between '2019-02-12' and '2019-02-12'
and datepart(dw,d.[date]) not in (1,7)
and DistrictCode = 'MA'
and FiscalYear = '2019'
and summerSchool = '0'
and left(SchoolCode,1) = '0'
and e.type IS NULL
select sts='success', result= convert( varchar,##rowcount) + ' rows updated.';
set #rowcount = (select ##rowcount);
Related
I am running the below query which is failing when it fills up the tempdb (170GB). It fails after around 1 hour.
the script below :
--Select Query BOM collection retail report
Declare #Company Nvarchar(50) ='HMFI'
Declare #Product Nvarchar(50) =Null
select Upper (Be.DataAreaId)Company ,BE.BOM,BE.Product
,Max(ProItemName)ProItemName
,Max(ProUnitID)ProUnitID
,Be.Material,Max(MaterialItemName)MaterialItemName
,Be.UNITID MaterialUnitID
,Sum (Be.BOMQTY)MaterialQty
,Max (MaterialService) MaterialType
from ExpBom_HMFI BE
Outer Apply (SELECT UNITID ProUnitID FROM INVENTTABLEMODULE A With (Nolock) WHERE DATAAREAID = #Company AND A.ITEMID =BE.Product AND MODULETYPE = 0)ProUnitID
Outer Apply(SELECT ITEMNAME ProItemName FROM INVENTTABLE B With (Nolock) WHERE DATAAREAID = #Company AND B.ITEMID = BE.Product)ProItemName
Outer Apply(SELECT ITEMNAME MaterialItemName FROM INVENTTABLE C With (Nolock) WHERE DATAAREAID = #Company AND C.ITEMID = Be.Material)MaterialItemName
Outer Apply(SELECT Case When ITEMTYPE=0 Then 'Item' When ITEMTYPE=1 Then 'BOM' When ITEMTYPE=2 Then 'Service Item' End MaterialService
FROM INVENTTABLE With (Nolock) WHERE DATAAREAID = #Company AND ITEMID = Be.Material)MaterialService
Where BE.DataAreaId in (#Company) and (#Product Is null Or Be.Product In(Select StringValue From Split(#Product,',')))
Group by Be.DataAreaId,BE.BOM,BE.Product,Be.Material ,Be.UNITID
Order By Be.DataAreaId,BE.BOM,BE.Product,Be.Material
option (maxrecursion 0)
--now Viewing the data collected
with ExpBom (
DataAreaId,
Bom,
Product,
Material,
BomDepth,
BOMQTY,
Unitid,
BomPath
) as (
select
bv.DataAreaId,
bv.BomId,
bv.ItemId,
b.ItemId,
1,
Convert (NUMERIC(18,8), b.BOMQTY) BOMQTY,
Convert (Nvarchar(10),b.UNITID )Unitid,
convert(Nvarchar(max), bv.ItemId + '|' + b.ItemId) as BomPath
from BomVersion bv With (Nolock)
join InventTable ibv With (Nolock)
on ibv.DataAreaId = bv.DataAreaId
and ibv.ItemId = bv.ItemId
join Bom b With (Nolock)
on b.DataAreaId = bv.DataAreaId
and b.BomId = bv.BomId
join InventTable ib With (Nolock)
on ib.DataAreaId = b.DataAreaId
and ib.ItemId = b.ItemId
where bv.Approved = 1
and bv.Active = 1
and bv.FromDate < getdate()
and (bv.ToDate = '01-01-1900' or bv.ToDate >= getdate())
and b.FromDate < getdate()
and (b.ToDate = '01-01-1900' or b.ToDate >= getdate())
and b.DATAAREAID in ('HMFI')
union all
select
bv.DataAreaId,
bv.BomId,
bv.ItemId,
eb.Material,
eb.BomDepth + 1,
Convert (NUMERIC(18,8),B.BOMQTY * eb.BOMQTY)BOMQTY,
Convert (Nvarchar(10),eb.UNITID )Unitid,
convert(Nvarchar(max), bv.ItemId + '|' + eb.BomPath) as BomPath
from BomVersion bv With (Nolock)
join InventTable ibv With (Nolock)
on ibv.DataAreaId = bv.DataAreaId
and ibv.ItemId = bv.ItemId
join Bom b With (Nolock)
on b.DataAreaId = bv.DataAreaId
and b.BomId = bv.BomId
join ExpBom eb
on eb.DataAreaId = b.DataAreaId
and eb.Product = b.ItemId
where bv.Approved = 1
and bv.Active = 1
and bv.FromDate < getdate()
and (bv.ToDate = '01-01-1900' or bv.ToDate >= getdate())
and b.FromDate < getdate()
and (b.ToDate = '01-01-1900' or b.ToDate >= getdate())
and b.DATAAREAID in ('HMFI')
)
select * from ExpBOM
Where Material Not in (Select BOMV.ITEMID From BomVersion BOMV With (Nolock) Where BOMV.DataAreaId In( 'HMFI' ) and BOMV.Approved = 1
and BOMV.Active = 1
and BOMV.FromDate < getdate()
and (BOMV.ToDate = '01-01-1900' or BOMV.ToDate >= getdate()) )
I'm not sure if the JOINS are causing the issue
Estimated execution plan is below:
Data collection :
https://www.brentozar.com/pastetheplan/?id=S1UsXn4Po
Data view:
https://www.brentozar.com/pastetheplan/?id=BJDUBn4wi
Please advise
this report was working fine on daily basis without filling tempdb usualy it was taking 1 min to execute suddenly it stoped for unknown reason although there's no changes done on server/database levels
Please how to combine maximum and distinct to have always unique Id and maximum of the column for that unique Id?
For example, if I have,
OrdinaceId Priloha2Id
5 1
5 2
6 2
6 4
7 1
result will be
OrdinaceId Priloha2Id
5 2
6 4
7 1
how to return only 1 row(with the same Id) with a maximum of Priloha2Id?
select * from (select
distinct ord.Id as OrdinaceId,
ord.CleneniPzsId,
posk.Id,
posk.ICO as Ico,
zar.ICZ as Icz,
posk.NazevZkraceny as Zkratka,
case when cle.Primariat = 0 then cle.Icp end as Icp,
IIF(cle.Primariat = 1, pri.OborKod , cle.OdbornostKod) as OdbornostKod,
ord.Nazev as OrdinaceNazev,
(select Street + N' ' + DescriptiveNo + N', ' + PostCode + N' ' + City from ICIS_Repl.repl.Address where Code = ord.NavAddressCode and Type = N'ORDINACE' and (ValidFrom is null or ValidFrom <= GETDATE()) and (ValidTill is null or ValidTill >= GETDATE() or ValidTill = N'1753-01-01 00:00:00')) as OrdinaceAdresaCela,
pril.Id as Priloha2Id,
cle.Smluvni,
cisP2KomunikaceStav.Nazev as EP2,
cisPzs.Nazev as StavPzp,
pril.Status,
pril.Info,
pril.PriPlatnostOd as PlatnostOd,
pril.PriPlatnostDo as PlatnostDo
from Ordinace ord
left join CleneniPzs cle on cle.Id = ord.CleneniPzsId
left join ZarizeniPZS zar on cle.ZarizeniPzsId = zar.Id
left join PoskytovatelZS posk on zar.PoskytovatelZsId = posk.Id
left join Primariat pri on cle.PrimariatId = pri.Id
left join Pril2Formular pr on pr.CleneniPzsId = cle.Id
left join Priloha2 pril on pril.Id = pr.Priloha2Id and (pril.PriPlatnostOd <= GETDATE() or pril.PriPlatnostOd is null) and (pril.PriPlatnostDo is null or pril.PriPlatnostDo >= GETDATE())
join CisCiselnik cisP2KomunikaceStav on posk.P2KomunikaceStavKod = cisP2KomunikaceStav.Kod AND cisP2KomunikaceStav.Oblast = N'P2KomunikaceStav' and cisP2KomunikaceStav.PlatnostOd <= GETDATE() and (cisP2KomunikaceStav.PlatnostDo is null or cisP2KomunikaceStav.PlatnostDo >= GETDATE())
left join P2Formular form on form.Icp = cle.Icp and form.Aktivni = 1
left join CisCiselnik cisPzs on form.P2StavPzpKod = cisPzs.Kod AND cisPzs.Oblast = N'P2StavPZP' and cisPzs.PlatnostOd <= GETDATE() and (cisPzs.PlatnostDo is null or cisPzs.PlatnostDo >= GETDATE())
left join P2ZarizeniPZS z on form.P2ZarizeniPzsId = z.Id and z.Icz = zar.ICZ and z.PoskytovatelZsId = posk.Id
join Smlouva smlv on smlv.Id = pril.SmlouvaId
left join SmluvniVykon smlVyk on smlVyk.CleneniPzsId = cle.Id and smlVyk.PlatnostOd <= GETDATE() and (smlVyk.PlatnostDo is null or smlVyk.PlatnostDo >= GETDATE())
left join SmlVykonVyjadreniRL vyjadreni on vyjadreni.Id = smlVyk.VyjadreniRLId ) a
You may use CTE to get max(Priloha2Id) per id. Then join to it.
Something like:
;with Pril2Formular_max_per_id as (
select ord.Id as OrdinaceId, max(pr.Priloha2Id) as max_Priloha2Id
from Ordinace ord
left join CleneniPzs cle on cle.Id = ord.CleneniPzsId
left join Pril2Formular pr on pr.CleneniPzsId = cle.Id
group by ord.Id
)
select * from (select
distinct ord.Id as OrdinaceId,[![enter image description here][1]][1]
ord.CleneniPzsId,
posk.Id,
posk.ICO as Ico,
zar.ICZ as Icz,
posk.NazevZkraceny as Zkratka,
case when cle.Primariat = 0 then cle.Icp end as Icp,
IIF(cle.Primariat = 1, pri.OborKod , cle.OdbornostKod) as OdbornostKod,
ord.Nazev as OrdinaceNazev,
(select Street + N' ' + DescriptiveNo + N', ' + PostCode + N' ' + City from ICIS_Repl.repl.Address where Code = ord.NavAddressCode and Type = N'ORDINACE' and (ValidFrom is null or ValidFrom <= GETDATE()) and (ValidTill is null or ValidTill >= GETDATE() or ValidTill = N'1753-01-01 00:00:00')) as OrdinaceAdresaCela,
pril.Id as Priloha2Id,
cle.Smluvni,
cisP2KomunikaceStav.Nazev as EP2,
cisPzs.Nazev as StavPzp,
pril.Status,
pril.Info,
pril.PriPlatnostOd as PlatnostOd,
pril.PriPlatnostDo as PlatnostDo
from Ordinace ord
left join CleneniPzs cle on cle.Id = ord.CleneniPzsId
left join ZarizeniPZS zar on cle.ZarizeniPzsId = zar.Id
left join PoskytovatelZS posk on zar.PoskytovatelZsId = posk.Id
left join Primariat pri on cle.PrimariatId = pri.Id
left join Pril2Formular_max_per_id pr on pr.OrdinaceId = ord.Id
left join Priloha2 pril on pril.Id = pr.max_Priloha2Id and (pril.PriPlatnostOd <= GETDATE() or pril.PriPlatnostOd is null) and (pril.PriPlatnostDo is null or pril.PriPlatnostDo >= GETDATE())
join CisCiselnik cisP2KomunikaceStav on posk.P2KomunikaceStavKod = cisP2KomunikaceStav.Kod AND cisP2KomunikaceStav.Oblast = N'P2KomunikaceStav' and cisP2KomunikaceStav.PlatnostOd <= GETDATE() and (cisP2KomunikaceStav.PlatnostDo is null or cisP2KomunikaceStav.PlatnostDo >= GETDATE())
left join P2Formular form on form.Icp = cle.Icp and form.Aktivni = 1
left join CisCiselnik cisPzs on form.P2StavPzpKod = cisPzs.Kod AND cisPzs.Oblast = N'P2StavPZP' and cisPzs.PlatnostOd <= GETDATE() and (cisPzs.PlatnostDo is null or cisPzs.PlatnostDo >= GETDATE())
left join P2ZarizeniPZS z on form.P2ZarizeniPzsId = z.Id and z.Icz = zar.ICZ and z.PoskytovatelZsId = posk.Id
join Smlouva smlv on smlv.Id = pril.SmlouvaId
left join SmluvniVykon smlVyk on smlVyk.CleneniPzsId = cle.Id and smlVyk.PlatnostOd <= GETDATE() and (smlVyk.PlatnostDo is null or smlVyk.PlatnostDo >= GETDATE())
left join SmlVykonVyjadreniRL vyjadreni on vyjadreni.Id = smlVyk.VyjadreniRLId ) a ;
select Id, max(Priloha2Id) from table group by Id
I have a two part question.
First part is about the speed of what I am doing below. I am taking a data set and getting each DISTINCT, then joining a subquery that sums/counts with criteria, then repeating that five times. After the first LEFT JOIN I have a run time of 02 seconds, after the second LEFT JOIN I have a run time of 04 seconds, but on the third LEFT JOIN my run time goes to 44 seconds. If that pull that query aside and run it alone, it is just 01 second. The total run time for the finished query is 70 seconds.
First part question:
What is making this query dramatically slower at the third join?
Second part: I am sure that I am accomplishing this in an inefficient way. I looked around for a while and was unable to find a way to accomplish what I am doing in a simple way while still being able to have different criteria for each subquery.
Second part question:
Is there a better way of accomplishing this query?
Edit after user1413's comment.
SELECT DISTINCT at the beginning was showing 49% cost in SQL Server execution plan view. I changed the table that the SELECT DISTINCT was selecting from and my run time went down to below 01 second.
SELECT DISTINCT
od.location, currentTires, currentAlignments, currentLubes,
currentBatteries,currentSiping,currentCarcount
FROM
comm.dbo.ordetail as od
LEFT JOIN
(SELECT
od2.location, SUM(od2.qty_shipped) as currentTires
FROM
comm.dbo.ordetail as od2
JOIN
comm.dbo.invmas as invmas2 ON invmas2.item_num = od2.item#
JOIN
comm.dbo.ordhrd as oh2 ON oh2.location = od2.location
AND oh2.inv_date = od2.inv_date
AND oh2.invoice# = od2.invoice#
WHERE
(oh2.type_of_rec = '01' OR oh2.type_of_rec = '02')
AND od2.inv_date >= '2017-02-01 00:00:00.000'
AND od2.inv_date <= '2017-02-28 00:00:00.000'
AND ( invmas2.category = 'uhp' OR invmas2.category = 'tour' OR invmas2.category = 'mass' OR invmas2.category = 'suv' OR invmas2.category = 'ltat' OR invmas2.category = 'ltmt' OR invmas2.category = 'lthwy' OR invmas2.category = 'snow' OR invmas2.category = 'stdls' )
GROUP BY
od2.location) as currentTires ON od.location = currentTires.location
LEFT JOIN
(SELECT
od3.location, SUM(od3.qty_shipped) as currentAlignments
FROM
comm.dbo.ordetail as od3
JOIN
comm.dbo.invmas as invmas3 ON invmas3.item_num = od3.item#
JOIN
comm.dbo.ordhrd as oh3 ON oh3.location = od3.location
AND oh3.inv_date = od3.inv_date
AND oh3.invoice# = od3.invoice#
WHERE
(oh3.type_of_rec = '01' OR oh3.type_of_rec = '02')
AND od3.inv_date >= '2017-02-01 00:00:00.000'
AND od3.inv_date <= '2017-02-28 00:00:00.000'
AND (od3.item# = '8501' OR od3.item# = '8502')
GROUP BY
od3.location) as currentAlignments ON od.location = currentAlignments.location
LEFT JOIN
(SELECT
od4.location, SUM(od4.qty_shipped) as currentLubes
FROM
comm.dbo.ordetail as od4
JOIN
comm.dbo.invmas as invmas4 ON invmas4.item_num = od4.item#
JOIN
comm.dbo.ordhrd as oh4 ON oh4.location = od4.location
AND oh4.inv_date = od4.inv_date
AND oh4.invoice# = od4.invoice#
WHERE
(oh4.type_of_rec = '01' OR oh4.type_of_rec = '02')
AND od4.inv_date >= '2017-02-01 00:00:00.000'
AND od4.inv_date <= '2017-02-28 00:00:00.000'
AND (od4.item# = '200fs' OR od4.item# = '200c' OR od4.item# = '200m' OR od4.item# = '200s')
GROUP BY
od4.location) as currentLubes ON od.location = currentLubes.location
LEFT JOIN ( SELECT od5.location,SUM(od5.qty_shipped) as currentBatteries
FROM comm.dbo.ordetail as od5
JOIN comm.dbo.invmas as invmas5
ON invmas5.item_num = od5.item#
JOIN comm.dbo.ordhrd as oh5
ON oh5.location = od5.location
AND oh5.inv_date = od5.inv_date
AND oh5.invoice# = od5.invoice#
WHERE ( oh5.type_of_rec = '01' OR oh5.type_of_rec = '02' )
AND od5.inv_date >= '2017-02-01 00:00:00.000'
AND od5.inv_date <= '2017-02-28 00:00:00.000'
AND invmas5.manufact = 'inter'
GROUP BY od5.location) as currentBatteries
ON od.location = currentBatteries.location
LEFT JOIN ( SELECT od6.location,SUM(od6.qty_shipped) as currentSiping
FROM comm.dbo.ordetail as od6
JOIN comm.dbo.invmas as invmas6
ON invmas6.item_num = od6.item#
JOIN comm.dbo.ordhrd as oh6
ON oh6.location = od6.location
AND oh6.inv_date = od6.inv_date
AND oh6.invoice# = od6.invoice#
WHERE ( oh6.type_of_rec = '01' OR oh6.type_of_rec = '02' )
AND od6.inv_date >= '2017-02-01 00:00:00.000'
AND od6.inv_date <= '2017-02-28 00:00:00.000'
AND invmas6.manufact = 'inter'
GROUP BY od6.location) as currentSiping
ON od.location = currentSiping.location
LEFT JOIN ( SELECT od7.location,COUNT(DISTINCT oh7.invoice#) as currentCarcount
FROM comm.dbo.ordetail as od7
JOIN comm.dbo.ordhrd as oh7
ON oh7.location = od7.location
AND oh7.inv_date = od7.inv_date
AND oh7.invoice# = od7.invoice#
WHERE ( oh7.type_of_rec = '01' OR oh7.type_of_rec = '02' )
AND od7.inv_date >= '2017-02-01 00:00:00.000'
AND od7.inv_date <= '2017-02-28 00:00:00.000'
AND oh7.veh_make != ''
AND od7.item# != ''
GROUP BY od7.location) as currentCarcount
ON od.location = currentCarcount.location
ORDER BY od.location
Sample data output:
There are a lot of things that could be made better here. For starters, one of the following joins below could be eliminated as the same items are returned for both od5 and od6.
LEFT JOIN ( SELECT od5.location,SUM(od5.qty_shipped) as currentBatteries
FROM comm.dbo.ordetail as od5
JOIN comm.dbo.invmas as invmas5
ON invmas5.item_num = od5.item#
JOIN comm.dbo.ordhrd as oh5
ON oh5.location = od5.location
AND oh5.inv_date = od5.inv_date
AND oh5.invoice# = od5.invoice#
WHERE ( oh5.type_of_rec = '01' OR oh5.type_of_rec = '02' )
AND od5.inv_date >= '2017-02-01 00:00:00.000'
AND od5.inv_date <= '2017-02-28 00:00:00.000'
AND invmas5.manufact = 'inter'
GROUP BY od5.location) as currentBatteries
ON od.location = currentBatteries.location
LEFT JOIN ( SELECT od6.location,SUM(od6.qty_shipped) as currentSiping
FROM comm.dbo.ordetail as od6
JOIN comm.dbo.invmas as invmas6
ON invmas6.item_num = od6.item#
JOIN comm.dbo.ordhrd as oh6
ON oh6.location = od6.location
AND oh6.inv_date = od6.inv_date
AND oh6.invoice# = od6.invoice#
WHERE ( oh6.type_of_rec = '01' OR oh6.type_of_rec = '02' )
AND od6.inv_date >= '2017-02-01 00:00:00.000'
AND od6.inv_date <= '2017-02-28 00:00:00.000'
AND invmas6.manufact = 'inter'
GROUP BY od6.location) as currentSiping
ON od.location = currentSiping.location
As for performance and readability try something like below. NOTE : I can not possibly test this, however, it may give insight to someone with more time to fiddle with performance tuning your query.
DECLARE #LowDate DATETIME = '2017-02-01 00:00:00.000'
DECLARE #HighDate DATETIME = '2017-02-28 00:00:00.000'
SELECT
DetailList.location,
currentTires = SUM(currentTires),
currentAlignments = SUM(currentAlignments),
currentLubes = SUM(currentLubes),
currentBatteries = SUM(currentBatteries),
currentSiping = SUM(currentSiping),
carCount = SUM(hasCar)
FROM
(
SELECT
od.location,
currentLubes=CASE WHEN ( od.item# = '200fs' OR od.item# = '200c' OR od.item# = '200m' OR od.item# = '200s' ) THEN od.qty_shipped ELSE NULL END,
currentAlignments=CASE WHEN ( od.item# = '8501' OR od.item# = '8502' ) THEN od.qty_shipped ELSE NULL END,
currentSiping = CASE WHEN ( invmas.item_num = 'p15' OR invmas.item_num = 'u15' ) THEN od.qty_shipped ELSE NULL END,
currentBatteries = CASE WHEN invmas.manufact = 'inter' THEN od.qty_shipped ELSE NULL END,
currentTires= CASE WHEN ( invmas.category = 'uhp' OR invmas.category = 'tour' OR invmas.category = 'mass' OR invmas.category = 'suv' OR invmas.category = 'ltat' OR
invmas.category = 'ltmt' OR invmas.category = 'lthwy' OR invmas.category = 'snow' OR invmas.category = 'stdls' ) THEN od.qty_shipped ELSE NULL END,
hasCar= CASE WHEN (oh.veh_make != '' AND od.item# !='') THEN 1 ELSE 0 END
FROM
comm.dbo.ordetail as od
LEFT JOIN comm.dbo.invmas as invmas ON invmas.item_num = od.item# --FOR currentCarcount
INNER JOIN comm.dbo.ordhrd as oh ON oh.location = od.location AND oh.inv_date = od.inv_date AND oh.invoice# = od.invoice#
WHERE
od.inv_date BETWEEN '2017-02-01 00:00:00.000' AND '2017-02-28 00:00:00.000'
AND
oh.type_of_rec IN('01','02')
)AS DetailList
GROUP BY
DetailList.location
I have the below code but it takes tooooo much time to run. Is there any way to simplify it? I need the iotransactiondate depending on the iostatus on two different columns, that's why i had to join the same tables two times.
SELECT
pg.pgrpName1 [Santiye],
p.prsncode [Sicil No],
p.[prsnname1] [Adi],
p.[prsnname2] [Soyadi],
CLT.clntName1 [Firmasi],
fg3.grp3Name1 [Gorevi],
prf.pcntrName1 [Ekibi],
lnk11.lgrp11Name1 [Kaldigi Yer],
lnk12.lgrp12Name1 +' - '+lnk12.lgrp12Name2 [Kamp/Adres],
lnk13.lgrp13Name1 [Oda No],
ttt.[iotransactiondate] [Giris Tarihi/Saati],
tt.[iotransactiondate] [Cikis Tarihi/Saati],
prsnEText4 [Vardiya],
tz.tzoneName1 [GECE/GUNDUZ]
--ps.psStartDate,
--ps.psFinishDate,
--[Giris/Cikis] = ( CASE
-- WHEN [t.iostatus] = 0 THEN 'Giris'
-- WHEN [t.iostatus] = 1 THEN 'Cikis'
-- ELSE 'Uzaya Gitti'
-- END )
FROM [Exen].[dbo].[IOTransaction] t
LEFT JOIN dbo.person p
ON t.ioPrsnRefId = p.prsnRefId
LEFT JOIN dbo.PersonShift ps
ON ps.psPrsnRefId = p.prsnRefId
LEFT JOIN dbo.TimeZoneMess tz
ON tz.tzoneRefId = ps.psTzoneRefId
LEFT JOIN dbo.[PersonGroup] pg
ON pg.pgrpRefId = p.prsnPgrpRefId
LEFT JOIN FreeGroup3 fg3
ON fg3.grp3RefId = p.prsnGrp3RefId
left join Client CLT
ON CLT.clntRefId = P.prsnClntRefId
LEFT JOIN [ProfitCenter] prf
ON prf.pcntrRefId = p.prsnPcntrRefId
LEFT JOIN LinkedGroup11 lnk11
ON lnk11.lgrp11RefId = p.prsnLgrp11RefId
LEFT JOIN LinkedGroup12 lnk12
ON lnk12.lgrp12RefId = p.prsnLgrp12RefId
LEFT JOIN LinkedGroup13 lnk13
ON lnk13.lgrp13RefId = p.prsnLgrp13RefId
LEFT JOIN [Exen].[dbo].[IOTransaction] tt
ON t.ioPrsnRefId = tt.ioPrsnRefId and tt.[iostatus] = 1
LEFT JOIN [Exen].[dbo].[IOTransaction] ttt
ON t.ioPrsnRefId = ttt.ioPrsnRefId and ttt.[iostatus] = 0
WHERE ( t.[iotransactiondate] = (SELECT Min(m.[ioTransactionDate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS DATE)
= Cast
(
t.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId)
OR t.[iotransactiondate] = (SELECT Max(m.[iotransactiondate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS
DATE) =
Cast(
t.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId) )
AND p.[prsnname1] IS NOT NULL
AND t.iotransactiondate > '01.12.2016 00:00:00.000'
AND ps.psStartDate <= t.[iotransactiondate]
AND ps.psFinishDate > t.[iotransactiondate]
--and p.[prsnname1] ='NAIM'
AND tz.tzoneRefId =4
GROUP BY pg.pgrpName1 ,
t.ioPrsnRefId,
prsncode,
prsnname1,
prsnname2,
t.[iotransactiondate],
tt.[iotransactiondate],
ttt.[iotransactiondate],
t.iostatus,
tz.tzoneName1,
ps.psStartDate,
ps.psFinishDate,
prsnEText4,
fg3.grp3Name1,
CLT.clntName1,
prf.pcntrName1,
lgrp11Name1,
lgrp12Name1,
lgrp12Name2,
lgrp13Name1
ORDER BY P.prsncode, t.iotransactiondate desc
Especially this part takes too much time i guess, but i couldn't find another way.
LEFT JOIN [Exen].[dbo].[IOTransaction] tt
ON t.ioPrsnRefId = tt.ioPrsnRefId and tt.[iostatus] = 1
LEFT JOIN [Exen].[dbo].[IOTransaction] ttt
ON t.ioPrsnRefId = ttt.ioPrsnRefId and ttt.[iostatus] = 0
I removed the join parts (tt. and ttt.) and select the second time with a sub-query.
SELECT
pg.pgrpName1 [Santiye],
p.prsncode [Sicil No],
p.[prsnname1] [Adi],
p.[prsnname2] [Soyadi],
CLT.clntName1 [Firmasi],
fg3.grp3Name1 [Gorevi],
prf.pcntrName1 [Ekibi],
lnk11.lgrp11Name1 [Kaldigi Yer],
lnk12.lgrp12Name1 +' - '+lnk12.lgrp12Name2 [Kamp/Adres],
lnk13.lgrp13Name1 [Oda No],
t.[iotransactiondate] [Giris Tarihi/Saati],
(SELECT
t2.[iotransactiondate]
FROM [Exen].[dbo].[IOTransaction] t2
WHERE ( t2.[iotransactiondate] = (SELECT Min(m.[ioTransactionDate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t2.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS DATE)
= Cast
(
t2.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId)
OR t2.[iotransactiondate] = (SELECT Max(m.[iotransactiondate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t2.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS
DATE) =
Cast(
t2.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId) )
AND p.[prsnname1] IS NOT NULL
AND t2.iotransactiondate > '01.12.2016 00:00:00.000'
AND ps.psStartDate <= t2.[iotransactiondate]
AND ps.psFinishDate > t2.[iotransactiondate]
--and p.[prsnname1] ='NAIM'
--AND tz.tzoneRefId =4
and ioStatus = 1
and cast(t2.ioTransactionDate as date) = cast(t.ioTransactionDate as date) and t.ioPrsnRefId = t2.ioPrsnRefId
GROUP BY
t2.[iotransactiondate]
)
AS [Cikis Tarihi/Saati],
prsnEText4 [Vardiya],
tz.tzoneName1 [GECE/GUNDUZ]
--ps.psStartDate,
--ps.psFinishDate,
--[Giris/Cikis] = ( CASE
-- WHEN [t.iostatus] = 0 THEN 'Giris'
-- WHEN [t.iostatus] = 1 THEN 'Cikis'
-- ELSE 'Uzaya Gitti'
-- END )
FROM [Exen].[dbo].[IOTransaction] t
LEFT JOIN dbo.person p
ON t.ioPrsnRefId = p.prsnRefId
LEFT JOIN dbo.PersonShift ps
ON ps.psPrsnRefId = p.prsnRefId
LEFT JOIN dbo.TimeZoneMess tz
ON tz.tzoneRefId = ps.psTzoneRefId
LEFT JOIN dbo.[PersonGroup] pg
ON pg.pgrpRefId = p.prsnPgrpRefId
LEFT JOIN FreeGroup3 fg3
ON fg3.grp3RefId = p.prsnGrp3RefId
left join Client CLT
ON CLT.clntRefId = P.prsnClntRefId
LEFT JOIN [ProfitCenter] prf
ON prf.pcntrRefId = p.prsnPcntrRefId
LEFT JOIN LinkedGroup11 lnk11
ON lnk11.lgrp11RefId = p.prsnLgrp11RefId
LEFT JOIN LinkedGroup12 lnk12
ON lnk12.lgrp12RefId = p.prsnLgrp12RefId
LEFT JOIN LinkedGroup13 lnk13
ON lnk13.lgrp13RefId = p.prsnLgrp13RefId
WHERE ( t.[iotransactiondate] = (SELECT Min(m.[ioTransactionDate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS DATE)
= Cast
(
t.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId)
OR t.[iotransactiondate] = (SELECT Max(m.[iotransactiondate])
FROM IOTransaction m
WHERE m.ioPrsnRefId = t.ioPrsnRefId
AND Cast(m.[iotransactiondate] AS
DATE) =
Cast(
t.[iotransactiondate] AS DATE)
GROUP BY m.ioPrsnRefId) )
AND p.[prsnname1] IS NOT NULL
AND t.iotransactiondate > '01.12.2016 00:00:00.000'
AND ps.psStartDate <= t.[iotransactiondate]
AND ps.psFinishDate > t.[iotransactiondate]
--and p.[prsnname1] ='NAIM'
AND tz.tzoneRefId =4
and ioStatus = 0
GROUP BY pg.pgrpName1 ,
t.ioPrsnRefId,
prsncode,
prsnname1,
prsnname2,
t.[iotransactiondate],
t.iostatus,
tz.tzoneName1,
ps.psStartDate,
ps.psFinishDate,
prsnEText4,
fg3.grp3Name1,
CLT.clntName1,
prf.pcntrName1,
lgrp11Name1,
lgrp12Name1,
lgrp12Name2,
lgrp13Name1
I've got a web based report pulling out a load of information from our SQL server and wanted to know the best way of adding a "totals" row to the bottom. The query is full of subqueries, so I'm not sure of the best way of adding a summary row on the bottom.
I know the "best" way would be to do this in the presentation layer, but I've got sweet FA knowledge of the presentation layer (as the chap that made it has since left and no-one has the same skill set...!)
SELECT
dbo.Groups.GroupName, dbo.UserGroups.GroupId, dbo.Users.UserName + ' ' + dbo.Users.Surname AS Consultant,
dbo.UserGroups.UserId,
(SELECT COUNT(*) AS ManagerCount
FROM dbo.ClientContacts
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS ManagersAdded,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId = 1) AND (Createdon BETWEEN #startDate AND #endDate)) AS FirstInterviewCount,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews AS Interviews_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId in (1,3,4)) AND (Createdon BETWEEN #startDate AND #endDate)) AS InterviewCount,
(SELECT COUNT(*) AS InterviewCount
FROM dbo.Interviews AS Interviews_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (InterviewTypeId in (2)) AND (Createdon BETWEEN #startDate AND #endDate)) AS TelephoneCount,
(SELECT COUNT(*) AS DMSpokenTo
FROM dbo.NotebookItems
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 56) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS DMSpokenTo,
(SELECT COUNT(*) AS Appspokento
FROM dbo.NotebookItems
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 85) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS AppSpokenTo,
(SELECT COUNT(*) AS Marketed
FROM dbo.NotebookItems AS NotebookItems_1
WHERE (CreatedUserId = dbo.Users.UserId) AND (NotebookTypeId = 124) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Marketed,
(SELECT COUNT(*) AS CVSent
FROM dbo.ApplicantActions
WHERE (CreatedUserId = dbo.Users.UserId) AND (StatusId <> 28) AND (JobId IS NOT NULL) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS CVSent,
(SELECT COUNT(*) AS CVSent
FROM dbo.ApplicantActions
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Speccv,
(SELECT COUNT(*) AS Meetings
FROM dbo.DiaryEvents
WHERE (CreatedUserId = dbo.Users.UserId) AND (EventTypeID = 29) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS Meetings,
(SELECT COUNT(*) AS VacanciesAdded
FROM dbo.Jobs
WHERE (CreatedUserId = dbo.Users.UserId) AND (CreatedOn BETWEEN #startDate AND #endDate)) AS VacanciesAdded,
(SELECT SUM(pc.CommissionPerc / 100) AS PermPlacements
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId <> 6)) AS [Perm Placements],
(SELECT SUM(PlacementFee / 100 * pc.CommissionPerc) AS PermFee
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId <> 6)) AS [Perm Fee],
(SELECT SUM(pc.CommissionPerc / 100) AS ContractPlacements
FROM dbo.Placements
INNER JOIN PlacementConsultants pc on placements.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = placements.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (placements.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId = 6)) AS [Contract Placements],
(SELECT SUM(dbo.CONTRACT_NETT_VALUE_FOR_INITIAL_PLACEMENT(Placements_1.PlacementID) / 100 * pc.CommissionPerc) AS ContractFee
FROM dbo.Placements AS Placements_1
INNER JOIN PlacementConsultants pc on Placements_1.PlacementID = pc.PlacementId
INNER JOIN PlacementSectorDefinedColumns psdc on psdc.PlacementId = Placements_1.PlacementID
WHERE (isnull(psdc.notnewbusiness,'N') = 'N') AND (pc.UserId = dbo.Users.UserId) AND (Placements_1.CreatedOn BETWEEN #startDate AND #endDate) AND (PlacementTypeId = 6)) AS [Contract Value]
FROM dbo.Groups INNER JOIN
dbo.UserGroups ON dbo.Groups.GroupId = dbo.UserGroups.GroupId INNER JOIN
dbo.Users ON dbo.UserGroups.UserId = dbo.Users.UserId
WHERE (
(dbo.Users.Inactive = 'N') AND (dbo.UserGroups.GroupId = #GroupId) )
and users.userid not in (select userid from UserGroups where GroupId = 57)
One approach could be to do a UNION and then add in another set of subqueries, but that's going to get really messy and ridiculously long winded surely?
Is there a better way of doing it than that?
Try ROLLUP.
For performance reasons, I would consider using table variables or temp tables to avoid multiple queries of the same tables. Also, table variables and temp tables can have at least a primary key, whereas common table expressions are not indexed.
For example:
DECLARE #GroupName VARCHAR(100)
SELECT #GroupName = g.GroupName
FROM dbo.Groups g
WHERE g.GroupId = #GroupId
DECLARE #Users TABLE
(
UserId INT NOT NULL PRIMARY KEY,
Consultant VARCHAR(100) NOT NULL
)
INSERT #Users (UserId, Consultant)
SELECT u.UserId, u.UserName + ' ' + u.Surname
FROM dbo.Users u
INNER JOIN dbo.UserGroups ug ON u.UserId = ug.UserId AND ug.GroupId = #GroupId
WHERE u.Inactive = 'N'
AND NOT EXISTS (SELECT 1 FROM dbo.UserGroups ne
WHERE u.UserId = ne.UserId
AND ne.GroupId = 57)
DECLARE #ClientContacts TABLE
(
UserId INT NOT NULL PRIMARY KEY,
ManagerCount INT NOT NULL
)
INSERT #ClientContacts (UserId, ManagerCount)
SELECT u.UserId, COUNT(*)
FROM #Users u
INNER JOIN dbo.ClientContacts cc ON cc.CreatedUserId = u.UserId AND cc.CreatedOn BETWEEN #startDate AND #endDate
GROUP BY u.UserId
DECLARE #Interviews TABLE
(
UserId INT NOT NULL,
InterviewTypeId INT NOT NULL,
InterviewCount INT NOT NULL,
PRIMARY KEY (UserId, InterviewTypeId)
)
INSERT #Interviews (UserId, InterviewTypeId, InterviewCount)
SELECT u.UserId, i.InterviewTypeId, COUNT(*)
FROM #Users u
INNER JOIN dbo.Interviews i ON u.UserId = i.CreatedUserId AND i.InterviewTypeId BETWEEN 1 AND 4 AND i.CreatedOn BETWEEN #StartDate AND #EndDate
GROUP BY u.UserId, i.InterviewTypeId
-- Rest is an exercise for the reader, but:
SELECT #GroupName AS GroupName,
#GroupId AS GroupId,
CASE GROUPING(u.UserId) WHEN 1 THEN NULL ELSE MIN(u.Consultant) END AS Consultant,
u.UserId,
SUM(COALESCE(cc.ManagerCount, 0)) AS ManagersAdded,
SUM(COALESCE(ip.[1], 0)) AS FirstInterviewCount,
SUM(COALESCE(ip.[1], 0) + COALESCE(ip.[3], 0) + COALESCE(ip.[4], 0)) AS InterviewCount,
SUM(COALESCE(ip.[2], 0)) AS TelephoneCount
FROM #Users u
LEFT JOIN #ClientContacts cc ON u.UserId = cc.UserId
LEFT JOIN (SELECT i.UserId, i.InterviewTypeId, i.InterviewCount
FROM #Interviews i) AS ii
PIVOT (SUM(InterviewCount) FOR InterviewTypeId IN ([1], [2], [3], [4])) AS ip ON u.UserId = ip.UserId
GROUP BY ROLLUP(u.UserId)
ORDER BY GROUPING(u.UserId), u.UserId