I am working on performance optimizing my query. I have implemented two CTEs as well as created a couple of temporary tables. Finally I am writing a combined query that does the union on CTEs and joins with the temp table. I am sharing the code of where I am defining the CTE's and combined query.I have the following query and would like suggestions on what would be the best practice to improve speed.
;with histTbl_CTE
as (
select
a.companyid,
a.periodenddate,
a.pricingdate,
fp.fiscalYear,
fp.fiscalQuarter,
pt.periodtypeId
from (
/* determine the cartesian product of periodenddate and pricingdate, assigning
a periodenddate to every pricing date that is less than the periodenddate */
select
per.companyid,
periodenddate,
pric.pricingdate,
datediff(day, pricingdate, periodenddate) as peqdiffdate
from #PeriodTbl per
join #PricingTbl pric
on (per.companyid = pric.companyid
and per.periodenddate >= pric.pricingdate)
) a
inner join (
/*find the different between the pricing date and the period end date */
select
per.companyid,
periodenddate,
min(datediff(day, pricingdate, periodenddate)) minpeqdiffdate
from
#PeriodTbl per
join #PricingTbl pric
on (per.companyid = pric.companyid
and per.periodenddate >= pric.pricingdate)
group by per.companyid, per.fiscalyear, per.fiscalquarter, periodenddate
)b
on a.companyid = b.companyid
and a.periodenddate = b.periodenddate
and a.peqdiffdate = b.minpeqdiffdate
left join ciqFinPeriod fp on a.companyId = fp.companyId
left join ciqFinInstance fi on (a.periodenddate = fi.periodenddate
and fi.financialPeriodId = fp.financialPeriodId)
left join ciqPeriodType pt on pt.periodTypeId = fp.periodTypeId
where fi.latestforfinancialperiodflag = 1
and latestfilingforinstanceflag = 1
and pt.periodtypeid = 4
group by a.companyid, a.periodenddate, a.pricingdate, fp.fiscalYear, fp.fiscalQuarter, pt.periodtypeid
),
recentTbl_CTE
as (
--/* use the same methodology from above to find the most recent dates */
select
temp.companyId,
max(periodenddate) as periodenddate,
max(peqdate) as pricingDate,
x.adjFY as fiscalYear,
x.adjFQ as fiscalQuarter,
periodTypeId = NULL
from(
select
a.companyId,
a.periodenddate,
a.peqdate,
b.minpeqdiffdate
from(
select
mc.companyId,
mc.pricingDate as periodenddate,
peq.pricingDate as peqdate,
datediff(day, peq.pricingDate, mc.pricingDate) as peqdiffdate
from #MarketTbl mc
join #PricingTbl peq
on (mc.companyId = peq.companyId
and mc.pricingDate >=peq.pricingDate)
group by mc.companyid, mc.pricingDate, peq.pricingDate
) a
inner join (
select
mc.companyId,
mc.pricingdate as periodenddate,
min(datediff(day, peq.pricingDate, mc.pricingDate)) as minpeqdiffdate
from #MarketTbl mc
join #PricingTbl peq
on (mc.companyId = peq.companyId
and mc.pricingDate >= peq.pricingDate)
group by mc.companyid, mc.pricingDate
) b on
a.companyId = b.companyId
and a.periodenddate = b.periodenddate
and a.peqdiffdate = b.minpeqdiffdate
) temp
join #futurePer x on x.companyId = temp.companyId
group by temp.companyid, minpeqdiffdate, adjFY, adjFQ
having minpeqdiffdate = 0
)
/* combine all table and join the data*/
select
combined.companyId,
combined.periodenddate,
combined.dataItemName,
case when combined.dataItemName = 'priceMidUSD' then combined.dataItemidue/exR.currencyRateClose * 1
when combined.dataItemName = 'sharesOutstanding' then combined.dataItemidue
when combined.dataItemName = 'marketcaptrend' then combined.dataItemidue
else combined.dataItemidue/exR.currencyRateClose * 1e6 end as dataItemidue,
combined.fiscalYear,
combined.fiscalQuarter,
combined.periodTypeId,
ctbl.tickerSymbol,
ctbl.exchangeName,
id.dataItemId
from(
select
companyId,
pricingdate,
periodenddate,
currencyId,
dataItemName,
cast(dataItemidue as float) as dataItemidue,
fiscalYear,
fiscalQuarter,
periodTypeId
from(
select
a.companyId,
a.pricingdate,
c.currencyId,
a.periodenddate,
cast(c.priceMid as nvarchar(100)) as priceMidUSD,
cast(d.marketCap as nvarchar(100)) as marketCapUSD,
cast((d.marketCap/nullif(prevmc.prevmarketCap,0)) - 1 as nvarchar(100)) as marketcaptrend,
cast(d.TEV as nvarchar(100)) as TEV,
cast(d.sharesOutstanding as nvarchar(100)) as sharesOutstanding,
a.fiscalYear,
a.fiscalQuarter,
a.periodTypeId
from (
select
companyid,
periodenddate,
pricingdate,
fiscalYear,
fiscalQuarter,
periodtypeId
from histTbl_CTE
union all
select
companyId,
periodenddate,
pricingDate,
fiscalYear,
fiscalQuarter,
periodTypeId
from recentTbl_CTE
)a
join #PricingTbl c
on (
c.pricingdate = a.pricingDate
and c.companyId = a.companyId )
join #MarketTbl d
on (
d.companyId = a.companyId
and d.pricingDate = a.periodenddate)
left join (
select a.companyId,
a.pricingDate,
a.prevperiod,
b.marketcap as prevmarketcap
from(
select
mc.companyid,
mc.pricingdate,
mc.pricingdate -365 as 'prevperiod'
from
ciqMarketCap mc
where
mc.companyid in (select id from #companyId)
) a
inner join (
select
mc.companyId,
mc.pricingdate,
mc.marketcap
from #MarketTbl mc
) b
on (a.companyid = b.companyid
and a.prevperiod = b.pricingdate)
) prevmc
on (prevmc.companyid = d.companyid
and prevmc.pricingdate = d.pricingdate)
group by a.companyid, a.periodenddate, a.pricingDate, a.fiscalYear, a.fiscalQuarter, a.periodtypeid, c.currencyId,
c.pricemid, d.marketCap, d.TEV, d.sharesOutstanding, prevmc.prevperiod, prevmc.prevmarketcap
) c
unpivot
(dataItemidue for dataItemName in
(TEV, marketCapUSD, sharesOutstanding, marketcaptrend, priceMidUSD)
) as unpvt
) combined
join #CompanyInfoTbl ctbl on ctbl.companyId = combined.companyId
Related
I have a view in SQL server that i'm trying to convert to work in snowflake. The view uses two functions within it that are called to join onto another table.
I'm following steps provided by another user, but i'm getting lost somewhere in the middle and feel a little stuck.
Here is the query for the SQL Server view:
ALTER VIEW [proj].[pvw_PowerBI_ScrapList]
AS
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Manually Registered' AS RegistrationType
FROM (SELECT
CAST(SUM(sreg.ScrapQuantity) AS int) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM qms.ScrapRegistration sreg WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = sreg.ScrapReasonID -- creating CTE of this table
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, sreg.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, sreg.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID -- CREATE CTE OF THIS TABLE
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(e.ID, temp.DateTime) -- CREATE CTE OF THIS TABLE
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID) -- CREATE CTE OF THIS TABLE
UNION
SELECT
e.Name AS ProductionUnit,
temp.DateTime AS DateTime,
s.Reference AS Shift,
CONVERT(TIME, temp.DateTime) AS Time,
CONVERT(DATE, temp.DateTime - ISNULL((SELECT CAST(MIN(s_first.FromTimeOfDay) AS DateTime) FROM Shift s_first WHERE s_first.FromDay = s.FromDay AND s_first.ShiftCalendarID = s.ShiftCalendarID), CAST('6:00' AS DateTime))) AS ProductionDate,
temp.ScrapReason AS ScrapReason,
temp.Quantity AS ScrapQuantity,
'Auto Registered' AS RegistrationType
FROM (SELECT
SUM(ISNULL(asr.ScrapQuantity, 0)) AS Quantity,
sreas.Name As ScrapReason,
DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)) AS DateTime,
srer.EquipmentID AS EquipmentID
FROM proj.AutoScrapRegistration asr WITH (NOLOCK)
INNER JOIN qms.ScrapReason sreas WITH (NOLOCK) ON sreas.ID = asr.ScrapReasonID
INNER JOIN WorkRequest wr WITH (NOLOCK) ON wr.ID = asr.WorkRequestID
INNER JOIN SegmentRequirementEquipmentRequirement srer WITH (NOLOCK) ON srer.SegmentRequirementID = wr.SegmentRequirementID
GROUP BY DATEADD(MINUTE, 30 * (DATEPART(MINUTE, asr.ScrapTime) / 30), DATEADD(HOUR, DATEDIFF(HOUR, 0, asr.ScrapTime), 0)), srer.EquipmentID, sreas.Name) temp
INNER JOIN Equipment e WITH (NOLOCK) ON e.ID = temp.EquipmentID
INNER JOIN ShiftCalendar sc WITH (NOLOCK) ON sc.ID = dbo.cfn_GetEquipmentShiftCalendarID(temp.EquipmentID, temp.DateTime) -- the function is called here
INNER JOIN Shift s WITH (NOLOCK) ON s.ID = dbo.cfn_GetShiftIDFromDateTime(temp.DateTime, sc.ID) -- the function is called here
i'm ignoring the union for now to try and get something simply working.
The functions are highlighted in this post How to conver this SQL server Function into a CTE in snowflake
Here is what i have so far:
WITH table_ScrapRegistration (
Quantity
,ScrapReason
,DATETIME
,EquipmentID
,ScrapReasonID
,WorkRequestID
,SegmentRequirementID
)
AS (
SELECT CAST(SUM(sreg.ScrapQuantity) AS INT) AS Quantity
,sreas.Name AS ScrapReason
,DATEADD(MIN, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30)::INT, date_trunc('HOUR', sreg.ScrapTime)) AS DATETIME
,srer.EquipmentID AS EquipmentID
,sreas.ID AS ScrapReasonID
,wr.ID AS WorkRequestID
,srer.SegmentRequirementID AS SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.ScrapRegistration sreg
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.ScrapReason sreas ON sreas.ID = sreg.ScrapReasonID -- CREATE CTE OF THIS TABLE
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.WorkRequest wr ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN DB_BI_DEV.RAW_CPMS_LAG.SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY DATEADD(MIN, 30 * (DATE_PART(MINUTE, sreg.ScrapTime) / 30)::INT, date_trunc('HOUR', sreg.ScrapTime))
,srer.EquipmentID
,sreas.Name
,sreas.ID
,wr.ID
,srer.SegmentRequirementID
)
,table_scrapreason (
name
,ID
)
AS (
SELECT name
,ID
FROM DB_BI_DEV.RAW_CPMS_LAG.ScrapReason
)
,table_workrequest (
ID
,SegmentRequirementID
) -- this is from a join)
AS (
SELECT id
,SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.WorkRequest
)
,table_SegmentRequirementEquipmentRequirement (
EquipmentID
,SegmentRequirementID
)
AS (
SELECT EquipmentID
,SegmentRequirementID
FROM DB_BI_DEV.RAW_CPMS_LAG.SegmentRequirementEquipmentRequirement
)
,table_equipment (
id
,name
,ParentEquipmentID
,ShiftCalendarEntityNumber
)
AS (
SELECT id
,name
,ParentEquipmentID
,ShiftCalendarEntityNumber
FROM DB_BI_DEV.RAW_CPMS_LAG.Equipment
)
,table_ShiftCalendar (
id,
entitynumber,
begindate,
enddate,
name,
PeriodInDays
)
AS (
SELECT id,
entitynumber,
begindate,
enddate,
name,
PeriodInDays
FROM DB_BI_DEV.RAW_CPMS_LAG.ShiftCalendar)
,table_shift (
ID
,Reference
,FromDay
)
AS -- this is from the temp table
(
SELECT ID
,Reference
,FromDay
FROM DB_BI_DEV.RAW_CPMS_LAG.shift
)
,temp_sub_select
AS (
SELECT sreg.Quantity AS Quantity
,sreas.name AS ScrapReason
,timeadd('minute', TRUNCATE (minute(sreg.DATETIME) / 30) * 30, date_trunc('hour', sreg.DATETIME)) AS DATETIME
,srer.EquipmentID AS EquipmentID
FROM table_ScrapRegistration sreg
INNER JOIN table_scrapreason sreas ON sreas.ID = sreg.ScrapReasonID -- CREATE CTE OF THIS TABLE
INNER JOIN table_workrequest wr ON wr.ID = sreg.WorkRequestID -- CREATE CTE OF THIS TABLE
INNER JOIN table_SegmentRequirementEquipmentRequirement srer ON srer.SegmentRequirementID = wr.SegmentRequirementID -- CREATE CTE OF THIS TABLE
GROUP BY sreg.Quantity
,sreas.name
,timeadd('minute', TRUNCATE (minute(sreg.DATETIME) / 30) * 30, date_trunc('hour', sreg.DATETIME))
,srer.EquipmentID
)
--select * from cte_GetEquipmentShiftCalendarID_part_a
--when i run this i get results
, cte_GetEquipmentShiftCalendarID_part_a
as (
WITH recursive rec_cte(id, parentequipmentid, shiftcalendarentitynumber) AS (
SELECT ID,
ParentEquipmentID,
ShiftCalendarEntityNumber
FROM table_equipment
UNION ALL
SELECT r.ID,
p.ParentEquipmentID,
p.ShiftCalendarEntityNumber
FROM rec_cte AS r
INNER JOIN table_equipment p ON p.ID = r.ParentEquipmentID
AND r.ShiftCalendarEntityNumber IS NULL
)
SELECT c.id,
sc.id AS shiftCalendarID,
sc.begindate,
sc.enddate
FROM rec_cte AS c
LEFT JOIN table_shiftcalendar AS sc ON sc.entitynumber = c.ShiftCalendarEntityNumber
WHERE shiftcalendarentitynumber IS NOT NULL
)
select * from cte_GetEquipmentShiftCalendarID_part_a
-- when i run this, i dont get any results.
I have an sql query where I count receipts. I want to count a) all receipts, b) receipts where the related customer has registered in the same year/month, c) receipts where the related customer has visited the store at least 4 times. The query is grouped over year and month. I hope it is comprehensible.
SELECT t.Year, t.Month,
COUNT(DISTINCT fs.Receipt) AS NumberOfGuests, //fs.Receipt is Receipt Number
COUNT(DISTINCT
(CASE
WHEN YEAR(c.RegistrationDate) = t.Year AND MONTH(c.RegistrationDate) = t.Month
THEN fs.Receipt END)) AS NumberOfNewGuests,
COUNT(DISTINCT
(CASE WHEN
(
SELECT COUNT(DISTINCT fs_sub.Receipt)
FROM Dimension_Time AS t_sub
LEFT OUTER JOIN Fact_Sales AS fs_sub ON t_sub.ID = fs_sub.Time AND fs_sub.Store = #storeID
WHERE t_sub.Time = t.Time AND fs_sub.CustomerID = fs.CustomerID
) > 3
THEN fs.Receipt END)) AS NumberOfRegularGuests
FROM Dimension_Time AS t
LEFT OUTER JOIN Fact_Sales AS fs ON t.ID = fs.Time AND fs.Store = #storeID
LEFT OUTER JOIN Dimension_Customer AS c ON fs.Customer = c.ID
WHERE (t.Time >= DATEFROMPARTS(2021 - 1, 5, 1)) AND (t.Time <= EOMONTH(DATEFROMPARTS(2021, 5, 1)))
GROUP BY t.Month, t.Year
ORDER BY t.Year, t.Month
NumberOfGuests and NumberOfNewGuests works fine, but with NumberOfRegularGuests, I get an error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
Is it possible to build the query another way to avoid the error?
You can put the subquery into an APPLY:
SELECT t.Year, t.Month,
COUNT(DISTINCT fs.Receipt) AS NumberOfGuests, //fs.Receipt is Receipt Number
COUNT(DISTINCT
(CASE
WHEN YEAR(c.RegistrationDate) = t.Year AND MONTH(c.RegistrationDate) = t.Month
THEN fs.Receipt END)) AS NumberOfNewGuests,
COUNT(DISTINCT
(CASE WHEN t2.countReceipts > 3 THEN fs.Receipt END)
) AS NumberOfRegularGuests
FROM Dimension_Time AS t
LEFT OUTER JOIN Fact_Sales AS fs ON t.ID = fs.Time AND fs.Store = #storeID
LEFT OUTER JOIN Dimension_Customer AS c ON fs.Customer = c.ID
OUTER APPLY (
SELECT COUNT(DISTINCT fs_sub.Receipt) AS countReceipts
FROM Dimension_Time AS t_sub
LEFT OUTER JOIN Fact_Sales AS fs_sub ON t_sub.ID = fs_sub.Time AND fs_sub.Store = #storeID
WHERE t_sub.Time = t.Time AND fs_sub.CustomerID = fs.CustomerID
) t2
WHERE (t.Time >= DATEFROMPARTS(2021 - 1, 5, 1)) AND (t.Time <= EOMONTH(DATEFROMPARTS(2021, 5, 1)))
GROUP BY t.Month, t.Year
ORDER BY t.Year, t.Month;
But a subquery of this type is usually pretty inefficient (although this can depend on indexing as well as cardinalities ie how much of Fact_Sales is actually being used after filtering on dates). It can be replace by a windowed aggregate.
SELECT t.Year, t.Month,
COUNT(DISTINCT fs.Receipt) AS NumberOfGuests, //fs.Receipt is Receipt Number
COUNT(DISTINCT
(CASE
WHEN YEAR(c.RegistrationDate) = t.Year AND MONTH(c.RegistrationDate) = t.Month
THEN fs.Receipt END)) AS NumberOfNewGuests,
COUNT(DISTINCT
(CASE WHEN fs.countReceipts > 3 THEN fs.Receipt END)
) AS NumberOfRegularGuests
FROM Dimension_Time AS t
LEFT OUTER JOIN (
SELECT *,
COUNT(*) OVER (PARTITION BY fs.CustomerID) AS countReceipts
FROM Fact_Sales
) AS fs ON t.ID = fs.Time AND fs.Store = #storeID
LEFT OUTER JOIN Dimension_Customer AS c ON fs.Customer = c.ID
WHERE (t.Time >= DATEFROMPARTS(2021 - 1, 5, 1)) AND (t.Time <= EOMONTH(DATEFROMPARTS(2021, 5, 1)))
GROUP BY t.Month, t.Year
ORDER BY t.Year, t.Month;
It's unclear why you have COUNT(DISTINCT as opposed to just COUNT, this is usually an indication of a poorly thought-out join.
If it is indeed the case that there are multiple Fact_Sales with the same Receipt then you would need to change the window aggregate, as you cannot use COUNT(DISTINCT...) OVER...
SELECT t.Year, t.Month,
COUNT(DISTINCT fs.Receipt) AS NumberOfGuests, //fs.Receipt is Receipt Number
COUNT(DISTINCT
(CASE
WHEN YEAR(c.RegistrationDate) = t.Year AND MONTH(c.RegistrationDate) = t.Month
THEN fs.Receipt END)) AS NumberOfNewGuests,
COUNT(DISTINCT
(CASE WHEN fs.countReceipts > 3 THEN fs.Receipt END)
) AS NumberOfRegularGuests
FROM Dimension_Time AS t
LEFT OUTER JOIN (
SELECT *,
MAX(rn) OVER (PARTITION BY fs.CustomerID) AS countReceipts
FROM (
SELECT *,
DENSE_RANK() OVER (PARTITION BY fs.CustomerID ORDER BY fs.Receipt) AS rn
FROM Fact_Sales
) AS fs
) AS fs ON t.ID = fs.Time AND fs.Store = #storeID
LEFT OUTER JOIN Dimension_Customer AS c ON fs.Customer = c.ID
WHERE (t.Time >= DATEFROMPARTS(2021 - 1, 5, 1)) AND (t.Time <= EOMONTH(DATEFROMPARTS(2021, 5, 1)))
GROUP BY t.Month, t.Year
ORDER BY t.Year, t.Month;
Current query:
Select
FORMAT(Tracking.[start],'dd-MM-yyy H:m:s') as [start],
FORMAT(Tracking.[deliver],'yyy-MM-dd') as dateSort,
FORMAT(Tracking.[deliver],'dd-MM-yyyy') as deliver,
RTrim(Tracking.[orderNumber]) as orderNumber,
Tracking.[tcpState] as oTcpState,
Tracking.[transport],
Tracking.[orderType],
(SELECT Cast(SUM(Cast(stations.estimatedTime as decimal(18,2))/60 ) as decimal(18,2)) FROM stations WHERE stations.orderNumber = Tracking.orderNumber) AS oEstimatedTime,
JSON_VALUE(Tracking.[orderObj],'$."0".Referenztext') as Referenztext,
JSON_VALUE(Tracking.[orderObj],'$."0".TotalSW') as TotalSW,
stations.[id],
FORMAT(stations.[startdate],'dd-MM-yyyy') as startdate,
FORMAT(stations.[enddate],'dd-MM-yyyy') as enddate,
stations.[tcpState],
stations.[name],
stations.[estimatedTime],
stations.[pieces],
stations.[piecesDone],
FORMAT(stations.[estimatedStart],'dd-MM-yyyy') as estimatedStart,
FORMAT(stations.[estimatedEnd],'dd-MM-yyyy') as estimatedEnd,
from Tracking left JOIN(
Select * from Stations left JOIN (
Select dummy.id as dId, dummy.orderNumber as dOrderNumber, SUM(dummy.elapsedTime) as elapsedTimeStationObj From (
select orderNumber, id, DATEDIFF(mi,startdate,ISNULL(enddate,GETDATE())) as elapsedTime FROM StationObj
) dummy group by dummy.orderNumber, dummy.id
) as stationObj
on Stations.orderNumber = stationObj.dOrderNumber and Stations.id = stationObj.dId
where stations.deleted=0
) as stations
on Tracking.orderNumber = stations.orderNumber where Tracking.tcpState != 3
Would like to have the SUM from elapsedTimeStationObj as well.
Tried to do it like this below the other (SELECT Cast(SUM(Cast(stations.estimatedTime....:
(SELECT Cast(SUM(Cast(stations.elapsedTimeStationObj as decimal(18,2))) as decimal(18,2)) FROM stations WHERE stations.orderNumber = Tracking.orderNumber) AS requiredTime,
but it is not possible because elapsedTimeStationObj is not a attribute from table Stations.
Use it as a subquery, and you can use as CTE to make it readable and reusble, like this:
WITH CTE1
AS
(
SELECT DUMMY.id AS dId
,DUMMY.orderNumber AS dOrderNumber
,SUM(DUMMY.elapsedTime) AS elapsedTimeStationObj
FROM (
SELECT orderNumber
,id
,DATEDIFF(mi, startdate, ISNULL(enddate, GETDATE())) AS elapsedTime
FROM StationObj
) DUMMY
GROUP BY DUMMY.orderNumber
,DUMMY.id
), CTE2
AS
(
SELECT orderNumber, Cast(SUM(Cast(stations.estimatedTime as decimal(18,2))/60 ) as decimal(18,2)) AS oEstimatedTime
FROM stations
GROUP BY stations.orderNumber
)
SELECT FORMAT(Tracking.[start], 'dd-MM-yyy H:m:s') AS [start]
,FORMAT(Tracking.[deliver], 'yyy-MM-dd') AS dateSort
,FORMAT(Tracking.[deliver], 'dd-MM-yyyy') AS deliver
,RTrim(Tracking.[orderNumber]) AS orderNumber
,Tracking.[tcpState] AS oTcpState
,Tracking.[transport]
,Tracking.[orderType]
,s2.oEstimatedTime AS oEstimatedTime
,JSON_VALUE(Tracking.[orderObj], '$."0".Referenztext') AS Referenztext
,JSON_VALUE(Tracking.[orderObj], '$."0".TotalSW') AS TotalSW
,stations.[id]
,FORMAT(stations.[startdate], 'dd-MM-yyyy') AS startdate
,FORMAT(stations.[enddate], 'dd-MM-yyyy') AS enddate
,stations.[tcpState]
,stations.[name]
,stations.[estimatedTime]
,stations.[pieces]
,stations.[piecesDone]
,FORMAT(stations.[estimatedStart], 'dd-MM-yyyy') AS estimatedStart
,FORMAT(stations.[estimatedEnd], 'dd-MM-yyyy') AS estimatedEnd
,
FROM Tracking
LEFT JOIN (
SELECT *
FROM Stations
LEFT JOIN CTE1 AS stationObj ON Stations.orderNumber = stationObj.dOrderNumber
AND Stations.id = stationObj.dId
WHERE stations.deleted = 0
) AS stations ON Tracking.orderNumber = stations.orderNumber
LEFT JOIN CTE2 s2 ON stations.orderNumber = s2.orderNumber
WHERE Tracking.tcpState != 3
I have the following SQL query statement:
INSERT INTO #mt_API
SELECT
[dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=#StoreID
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
(
**select
case ISNULL(SUM([ProductItemWeight]), 0)
when 0 then 0
else SUM([ProductItemWeight])
end
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')**
)
) AS ItemWeightBal
FROM #mt_API AS API1
Inside the CASE statement I am returning the SUM([ProductItemWeight]) if it is not NULL, but then at same time, I need to execute the following inside the same CASE :
delete from #tempTransfert
where stuff(convert(varchar(20),#tempTransfert.TransferDate,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
ADDED MORE TEST :
If I run what I wan to accomplish in a standalone new query as below then the DELETE and SELECT works find inside the CASE
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),'2017-02-28 15:38:00',120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
BUT when I added in the complete query as below , I have a SYNTAX error near MERGE reported :
DECLARE #m_StoreTotalStock AS DECIMAL(18,3)
DECLARE #mt_API AS TABLE
(
ID INT IDENTITY(1,1), ASDATE DATETIME,ATDATE DATETIME,
ActionPlanItemID INT, ActionPlanID INT,
ProductItemID INT, ProductItemCode VARCHAR(50),
QRCode VARCHAR(50), Name VARCHAR(50),
StoreTotalStock decimal(18,3), ItemWeight decimal(18,3),
Unit VARCHAR(50), ItemQuantity INT,
ItemUnitWeight DECIMAL(18,4), ProductQuantity INT,
Emp1 VARCHAR(50), Emp2 VARCHAR(50),
Emp3 VARCHAR(50), Emp4 VARCHAR(50),
Sector VARCHAR(50), ItemStatus TINYINT,ActionOver INt
)
DECLARE #mt_RemainingStockProduct AS TABLE
(
StoreID INT,InventoryDate DATETIME,ProductID INT, TotalRemainingAtStore DECIMAL(18,2)
)
CREATE TABLE #tempTransfert
(
[ID] uniqueidentifier,
[ProductId] int,
[SourceId] int,
TransferDate DateTime,
TotalMovedProduct DECIMAL(16,4)
)
Insert into #tempTransfert
select
[ID],[ProductId], [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') as TransferDate, SUM([ProductItemWeight]) as TotalMovedProduct
from [ExplosiveTracking].[Production].[TransfertHistory]
group by [ProductId],ID, [SourceId], stuff(convert(varchar(20),TransfertDateTime,120),17,6,'')
select * from #tempTransfert
/** Get Remaining StockBy Product **/
INSERT INTO #mt_RemainingStockProduct
(
StoreID, InventoryDate, ProductID,TotalRemainingAtStore
)
--SELECT InventoryDate, SUM(TotalRemainingAtStore) AS TotalRemainingAtStore FROM
--(
SELECT StoreID, InventoryDate, ProductID, SUM(Remaining) OVER (PARTITION BY StoreID ) AS TotalRemainingAtStore FROM
(
SELECT
P.StoreID, P.InventoryDate, P.ProductID,
--SUM(PIT.Quantity * P.ItemUnitWeight)-SUM(PIT.UsedQuantity * P.ItemUnitWeight) AS Remaining
SUM(PIT.Quantity * P.ItemUnitWeight) AS Remaining
FROM Sales.Store AS S
INNER JOIN Production.ProductItem AS PIT
INNER JOIN Production.Product AS P ON PIT.ProductID = P.ProductID
INNER JOIN Production.UnitMeasure AS UM ON P.WeightUnitMeasureID = UM.UnitMeasureID ON
S.BusinessEntityID = P.StoreID
INNER JOIN Production.Location AS LOC ON S.BusinessEntityID = LOC.StoreID AND
P.LocationID = LOC.LocationID AND P.LocationID = LOC.LocationID
WHERE (P.IsDeleted = 0) AND (PIT.IsDeleted = 0) AND P.StoreID = 4
GROUP BY P.StoreID,P.InventoryDate, P.ProductID, UM.UnitMeasureCode, S.Name, LOC.MaxQuantity
) AS RST1
--) AS RST2
--GROUP BY RST2.InventoryDate
/** Endof Get Remaining StockBy Product **/
-- Get Store total product items weight
SELECT #m_StoreTotalStock = SUM(PIW.TotalWeight)
FROM dbo.v_ProductItemWeight AS PIW
WHERE StoreID = 4
INSERT INTO #mt_API
SELECT [dbo].fn_AddTimeZoneOffset(APHIST.ActionDate,'CET') AS ASDATE
, [dbo].fn_AddTimeZoneOffset(APHIST.ReturnDate,'CET') AS ATDATE
,API_HIST.[ActionPlanItemID]
,API_HIST.[ActionPlanID]
,PIT.[ProductItemID]
,PIT.ProductItemCode
,PIT.QRCode
,PIT.Name
,ISNULL((SELECT TOP 1 mRSP.TotalRemainingAtStore FROM #mt_RemainingStockProduct AS mRSP
WHERE mRSP.InventoryDate <= APHIST.ReturnDate
ORDER BY mRSP.InventoryDate DESC), 0) AS StoreTotalStock
,P.[Weight] AS ItemWeight
,M.UnitMeasureCode as Unit
,PIT.Quantity AS ItemQuantity
,P.ItemUnitWeight
,P.Quantity as ProductQuantity
,E1.FullName AS Emp1
,E2.FullName AS Emp2
,E3.FullName AS Emp3
,E4.FullName AS Emp4
,SECT.Name AS Sector
,CASE WHEN n=0 then 0 else [ItemStatus] end as [ItemStatus]
,APHIST.IsActionOver as ActionOver
FROM
[Sales].[ActionPlanItem_History] AS API_HIST
INNER JOIN
[Sales].[ActionPlan_History] AS APHIST On APHIST.ActionPlanID = API_HIST.ActionPlanID
INNER JOIN
[Production].[ProductItem] AS PIT ON API_HIST.ProductItemID =PIT.ProductItemID
INNER JOIN
Production.Product as P ON PIT.ProductID = P.ProductID AND PIT.ProductID = P.ProductID AND
PIT.ProductID = P.ProductID
INNER JOIN
Production.UnitMeasure as M ON M.UnitMeasureID = P.WeightUnitMeasureID
LEFT OUTER JOIN
Sales.Employee AS E1 ON APHIST.EmployeeID1 = E1.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E2 ON APHIST.EmployeeID2 = E2.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E3 ON APHIST.EmployeeID3 = E3.EmployeeID
LEFT OUTER JOIN
Sales.Employee AS E4 ON APHIST.EmployeeID4 = E4.EmployeeID
INNER JOIN
Sales.Sector AS SECT ON APHIST.SectorID = SECT.SectorID
INNER JOIN
Production.ProductSubcategory as PS on P.ProductSubcategoryID=PS.ProductSubcategoryID
INNER JOIN
Production.ProductCategory as PC on PS.ProductCategoryID= PC.ProductCategoryID
CROSS APPLY (Values(0),(1)) d(n)
WHERE P.StoreID=4
--WHERE PC.ProductCategoryID=#RootCategory AND P.StoreID=#StoreID
--ORDER BY ProductItemCode, ATDATE
ORDER BY ASDATE , ProductItemCode
SELECT
API1.ASDATE AS StartDate
,API1.ATDATE AS ReturnDate
,API1.ActionPlanItemID
,API1.ActionPlanID
,API1.ProductItemID
,API1.ProductItemCode
,API1.QRCode
,API1.Name
,API1.StoreTotalStock
,API1.ItemWeight
,API1.ItemQuantity
,API1.ItemUnitWeight
,API1.Unit
,API1.ProductQuantity
,API1.Emp1
,API1.Emp2
,API1.Emp3
,API1.Emp4
,API1.Sector
,API1.ItemStatus
,API1.ActionOver
,(API1.StoreTotalStock +
(SELECT SUM(
CASE API2.ItemStatus
WHEN 0 THEN -1
WHEN 1 THEN 1
ELSE 0
END * API2.ItemUnitWeight)
FROM #mt_API AS API2
WHERE API2.ID <= API1.ID
)
-
--select
-- case ISNULL(SUM([ProductItemWeight]), 0)
-- when 0 then 0
-- else SUM([ProductItemWeight])
-- end
--from [ExplosiveTracking].[Production].[TransfertHistory]
--where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
(
**MERGE #tempTransfert AS T
USING (select
case ISNULL(SUM([ProductItemWeight]) , 0)
when 0 then 0
else SUM([ProductItemWeight])
end
, ID
from [ExplosiveTracking].[Production].[TransfertHistory]
where stuff(convert(varchar(20),TransfertDateTime,120),17,6,'') < stuff(convert(varchar(20),API1.ASDATE,120),17,6,'')
Group by ID
) as S ([ProductItemWeight],ID)
ON (T.ID = S.ID)
WHEN MATCHED
THEN DELETE;
)**
) AS ItemWeightBal
FROM #mt_API AS API1
END
The MERGE part is suppose to first return the SUM of ItemWeight within a DateTime range, then when those records has been read, I need to delete them from #tempTransfert table otherwise, on the next loop it will read all records again
Any idea what syntax error can it be ?
Thanks for your help on this
Regards
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