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
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.
Using adventureworks database.
I am stuck with top 5 customers based on the territory. How can we get the output for this in the given format?
SELECT TOP 5 CustomerID
,oh.TerritoryID
,Name
,SUM(TotalDue) / (
SELECT SUM(TotalDue)
FROM Sales.SalesOrderHeader
) * 100 AS [%_of_TotalSale]
FROM Sales.SalesOrderHeader oh
INNER JOIN Sales.SalesTerritory st ON st.TerritoryID = oh.TerritoryID
GROUP BY oh.TerritoryID
,CustomerID
,Name
ORDER BY [%_of_TotalSale] DESC;
My output
The output should look like this
Your query have some issues. You need to calculated the total per territory - not the whole total.
Note, the code below can be separated to individual statements. Also, there are other solutions of this task.
WITH DataSource AS
(
SELECT DISTINCT TerritoryID
,CustomerID
,SUM(TotalDue) OVER (PARTITION BY TerritoryID,CustomerID) * 100 / SUM(TotalDue) OVER (PARTITION BY TerritoryID) AS [%_of_TotalSale]
FROM Sales.SalesOrderHeader
), DataSourceUsersRanked AS
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY TerritoryID ORDER BY [%_of_TotalSale] DESC) AS RN
FROM DataSource
), DataSourceUsersFiletred AS
(
SELECT *
FROM DataSourceUsersRanked
WHERE RN <= 5
)
SELECT DSF.TerritoryID
,st.[Name]
,SUM([%_of_TotalSale]) AS [%_of_TotalSale]
,MAX(UserIDs) AS [Top5Customers]
FROM DataSourceUsersFiletred DSF
INNER JOIN Sales.SalesTerritory st
ON DSF.TerritoryID = st.TerritoryID
CROSS APPLY
(
SELECT STUFF
(
(
SELECT ',' + CAST(CustomerID AS VARCHAR(12))
FROM DataSourceUsersFiletred DS1
WHERE DS1.[TerritoryID] = DSF.[TerritoryID]
ORDER BY CustomerID
FOR XML PATH(''), TYPE
).value('.', 'VARCHAR(MAX)')
,1
,1
,''
)
) Users(UserIDs)
GROUP BY DSF.TerritoryID
,st.[Name]
ORDER BY TerritoryID;
I have two tables (from two different systems) that track the employees' hours. In both tables, the employees enter the date and hours. I need to create an audit report that shows the discrepancy. The report needs to show all the columns and display a null/no match if there is a mismatch. One table might have more/less entries than the other table or even duplicate entries and I need to catch that (two entries on the same day for the same amount of hours in one table). Both tables have UserID that can be joined on.
If there is match based on date and hours, show all the values.
If there is a mismatch based on hours, show null or no match when there is mismatch.
If there is a duplicate entry, like the image below, match the first entry and report the second one as null or no match.
I tried joining the tables based UserID, date, and hours but not able to tell where the mismatch came from.
Table A:
Table B:
Left Join on UserID, date, and hours
SET NOCOUNT ON;
declare #table1 table
(
userid int,
entry_date date,
[hours] varchar(10)
)
declare #table2 table
(
userid int,
entry_date datetime,
[hours] varchar(10)
)
INSERT INTO #table1
select 1,'8/14/2017','10:00'
INSERT INTO #table1
select 2,'8/14/2017','5:00'
INSERT INTO #table1
select 2,'8/14/2017','5:00'
INSERT INTO #table1
select 2,'8/14/2017','5:00'
INSERT INTO #table1
select 2,'8/14/2017','5:00'
INSERT INTO #table1
select 3,'8/14/2017','5:00'
INSERT INTO #table1
select 3,'8/14/2017','6:00'
INSERT INTO #table1
select 3,'8/14/2017','6:00'
INSERT INTO #table1
select 3,'8/14/2017','6:00'
INSERT INTO #table2
select 1,'8/14/2017','10:00'
INSERT INTO #table2
select 2,'8/14/2017','8:00'
INSERT INTO #table2
select 3,'8/14/2017','6:00'
INSERT INTO #table2
select 4,'8/14/2017','2:00'
INSERT INTO #table2
select 1,'8/14/2017','10:00'
INSERT INTO #table2
select 3,'8/14/2017','6:00'
;WITH CTE_TABLE1 AS
(
select t.userid as userid, CAST(t.entry_date as DATE) as entry_date, t.[hours] as [hours],
ROW_NUMBER() OVER(PARTITION BY t.userid, t.entry_date, t.[hours] ORDER BY t.[Hours]) as rnk
from #Table1 t
), CTE_TABLE2 AS
(
select t.userid as userid, CAST(t.entry_date as DATE) as entry_date, t.[hours] as [hours],
ROW_NUMBER() OVER(PARTITION BY t.userid, t.entry_date, t.[hours] ORDER BY t.[Hours]) as rnk
from #Table2 t
), CTE_MATCHES AS
(
select t1.userid as userid, t1.entry_date as entry_date, t1.[hours] as [hours], t1.rnk
from CTE_TABLE1 t1
inner join CTE_TABLE2 t2
on (t1.userid = t2.userid AND t1.entry_date = t2.entry_date AND t1.[hours] = t2.[hours] AND t1.rnk = t2.rnk)
),CTE_MATCH_DUPLICATES AS
(
select 'Table1MatchDuplicate' as ErrorType, *
from
(
select t.*
from (select userid, entry_date, [hours], max(rnk) as rnk from CTE_MATCHES group by userid, entry_date, [hours]) m
inner join CTE_TABLE1 t
on (t.userid = m.userid AND t.entry_date = m.entry_date AND t.[hours] = m.[hours] AND t.rnk > m.rnk)
)q
UNION ALL
select 'Table2MatchDuplicate' as ErrorType, *
from
(
select t.*
from (select userid, entry_date, [hours], max(rnk) as rnk from CTE_MATCHES group by userid, entry_date, [hours]) m
inner join CTE_TABLE2 t
on (t.userid = m.userid AND t.entry_date = m.entry_date AND t.[hours] = m.[hours] AND t.rnk > m.rnk)
)q
)
, CTE_Table1_UNMATCHED AS
(
select t.userid, t.entry_date, t.[hours]
from #Table1 t
left outer join CTE_MATCHES m
on (t.userid = m.userid AND CAST(t.entry_date as DATE) = m.entry_date AND t.[hours] = m.[hours])
where m.userid is null
), CTE_Table2_UNMATCHED AS
(
select t.userid, t.entry_date, t.[hours]
from #Table2 t
left outer join CTE_MATCHES m
on (t.userid = m.userid AND CAST(t.entry_date as DATE) = m.entry_date AND t.[hours] = m.[hours])
where m.userid is null
)
select null as ErrorType, userid, entry_date, [hours] from CTE_MATCHES
UNION ALL
select 'Table1Mismatch' as ErrorType, userid, entry_date, [hours] from CTE_Table1_UNMATCHED
UNION ALL
select 'Table2Mismatch' as ErrorType, userid, entry_date, [hours] from CTE_Table2_UNMATCHED
UNION ALL
select ErrorType, userid, entry_date, [hours] from CTE_MATCH_DUPLICATES
order by ErrorType
http://rextester.com/UDG95824
if you need to find duplicates that had no matches as well:
,CTE_Table1_Unmatched_Duplicates AS
(
select userid, entry_date, [hours]
from CTE_Table1_UNMATCHED
group by userid, entry_date, [hours]
having count(*) > 1
),CTE_Table2_Unmatched_Duplicates AS
(
select userid, entry_date, [hours]
from CTE_Table2_UNMATCHED
group by userid, entry_date, [hours]
having count(*) > 1
)
...
UNION
select 'Table1UnmatchedDuplicates' as ErrorType, userid, entry_date, [hours] from CTE_Table1_Unmatched_Duplicates
UNION
select 'Table2UnmatchedDuplicates' as ErrorType, userid, entry_date, [hours] from CTE_Table2_Unmatched_Duplicates
http://rextester.com/KEJJF79330
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
I have the following query:
SELECT **top 1** account, date, result
FROM table_1 as t1
JOIN table_2 at t2 ON t1.accountId = t2.frn_accountId
WHERE accountID = 1
ORDER BY date
This query returns the result that I want however I want that result for multiple accountID. They query should return the top 1 value for each accountID.
The query that produce the list of the accountID-s is:
SELECT accountID from lskin WHERE refname LIKE '%BHA%' and isactive = 1
How can I write this query so it can produce the desired result? I have been playing around with CTE but haven't been able to make it correct. It doesn't have to be with CTE, I just thought it can be easier using CTE...
Here is CTE solution.
SELECT *
FROM (SELECT account
, date
, result
, ROW_NUMBER() OVER (PARTITION BY t1.accountId ORDER BY date DESC) AS Rownum
FROM table_1 AS t1
INNER JOIN table_2 AS t2
ON t1.accountId = t2.frn_accountId
INNER JOIN lskin AS l
ON l.accountID = t1.accountID
WHERE l.refname LIKE '%BHA%'
) a
WHERE a.Rownum = 1;
Use max on your date and group by the account, or what ever columns are appropriate.
SELECT
account,
DT = max(date),
result
FROM table_1 as t1
JOIN table_2 as t2 ON t1.accountId = t2.frn_accountId
JOIN lskin as l on l.accountID = t1.accountID
WHERE l.refname like '%BHA%'
GROUP BY
account
,result
If the grouping isn't correct, just join to a sub-query to limit it with max date. Just change the table names as necessary.
SELECT
account,
date,
result
FROM table_1 as t1
JOIN table_2 as t2 ON t1.accountId = t2.frn_accountId
JOIN lskin as l on l.accountID = t1.accountID
INNER JOIN (select max(date) dt, accountID from table_1 group by accountID) tt on tt.dt = t1.accountId and tt.accountId = t1.accountId
WHERE l.refname like '%BHA%'
Ignore the CTE at the top. That's just test data.
/* CTE Test Data */
; WITH table_1 AS (
SELECT 1 AS accountID, 'acc1' AS account UNION ALL
SELECT 2 AS accountID, 'acc2' AS account UNION ALL
SELECT 3 AS accountID, 'acc3' AS account
)
, table_2 AS (
SELECT 1 AS frn_accountID, 'new1' AS result, GETDATE() AS [date] UNION ALL
SELECT 1 AS frn_accountID, 'mid1' AS result, GETDATE()-1 AS [date] UNION ALL
SELECT 1 AS frn_accountID, 'old1' AS result, GETDATE()-2 AS [date] UNION ALL
SELECT 2 AS frn_accountID, 'new2' AS result, GETDATE() AS [date] UNION ALL
SELECT 2 AS frn_accountID, 'mid2' AS result, GETDATE()-1 AS [date] UNION ALL
SELECT 2 AS frn_accountID, 'old2' AS result, GETDATE()-2 AS [date] UNION ALL
SELECT 3 AS frn_accountID, 'new3' AS result, GETDATE() AS [date] UNION ALL
SELECT 3 AS frn_accountID, 'mid3' AS result, GETDATE()-1 AS [date] UNION ALL
SELECT 3 AS frn_accountID, 'old3' AS result, GETDATE()-2 AS [date]
)
, lskin AS (
SELECT 1 AS accountID, 'purple' AS refName, 1 AS isActive UNION ALL
SELECT 2 AS accountID, 'blue' AS refName, 1 AS isActive UNION ALL
SELECT 3 AS accountID, 'orange' AS refName, 0 AS isActive UNION ALL
SELECT 4 AS accountID, 'blue' AS refName, 1 AS isActive
)
,
/* Just use the below and remove comment markers around WITH to build Orders CTE. */
/* ; WITH */
theCTE AS (
SELECT s1.accountID, s1.account, s1.result, s1.[date]
FROM (
SELECT t1.accountid, t1.account, t2.result, t2.[date], ROW_NUMBER() OVER (PARTITION BY t1.account ORDER BY t2.[date]) AS rn
FROM table_1 t1
INNER JOIN table_2 t2 ON t1.accountID = t2.frn_accountID
) s1
WHERE s1.rn = 1
)
SELECT lskin.accountID
FROM lskin
INNER JOIN theCTE ON theCTE.accountid = lskin.accountID
WHERE lskin.refName LIKE '%blue%'
AND lskin.isActive = 1
;
EDITED:
I'm still making a lot of assumptions about your data structure. And again, make sure you're querying what you need. CTEs are awesome, but you don't want to accidentally filter out expected results.