MAX Date of multiple columns? - sql

How do you return 1 value per row of the max of several columns:
TableName [RefNumber, FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate]
I want MaxDate of (FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate) these dates for all rows in single column and I want another new column(Acion) depends on Max date column for ex: if Max date is from FirstVisitedDate then it will be 'FirstVisited' or if Max date is from SecondVisitedDate then it will be 'SecondVisited'...
The Total result Like:
Select RefNumber, Maxdate, Action From Table
group by RefNumber

The brute force approach isn't so bad with four columns:
select (case when FirstVisitedDate >= SecondVisitedDate and
FirstVisitedDate >= RecoveryDate and
FirstVisitedDate >= ActionDate
then FirstVisitedDate
when SecondVisitedDate >= RecoveryDate and
SecondVisitedDate >= ActionDate
then SecondVisitedDate
when RecoveryDate >= ActionDate
then RecoveryDate
else ActionDate
end),
(case when FirstVisitedDate >= SecondVisitedDate and
FirstVisitedDate >= RecoveryDate and
FirstVisitedDate >= ActionDate
then 'FirstVisitedDate'
when SecondVisitedDate >= RecoveryDate and
SecondVisitedDate >= ActionDate
then 'SecondVisitedDate'
when RecoveryDate >= ActionDate
then 'RecoveryDate'
else 'ActionDate'
end)
from table t;
EDIT:
Doing this in a group by is just a question of adding aggregation functions:
select RefNumber,
(case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
max(FirstVisitedDate) >= max(RecoveryDate) and
max(FirstVisitedDate) >= max(ActionDate)
then max(FirstVisitedDate
when max(SecondVisitedDate) >= max(RecoveryDate) and
max(SecondVisitedDate) >= max(ActionDate)
then max(SecondVisitedDate)
when max(RecoveryDate) >= max(ActionDate)
then max(RecoveryDate)
else max(ActionDate)
end),
(case when max(FirstVisitedDate) >= max(SecondVisitedDate) and
max(FirstVisitedDate) >= max(RecoveryDate) and
max(FirstVisitedDate) >= max(ActionDate)
then 'FirstVisitedDate'
when max(SecondVisitedDate) >= max(RecoveryDate) and
max(SecondVisitedDate) >= max(ActionDate)
then 'SecondVisitedDate'
when max(RecoveryDate) >= max(ActionDate)
then 'RecoveryDate'
else 'ActionDate'
end)
from table t
group by RefNumber;

;WITH cte AS (
-- Build table of date
SELECT [RefNumber],
[ActionDate]= [FirstVisitedDate],
[Action] = 'First Visited'
FROM [Table1]
UNION ALL
SELECT [RefNumber],
[SecondVisitedDate],
'Second Visited'
FROM [Table1]
UNION ALL
SELECT [RefNumber],
[RecoveryDate],
'Recover'
FROM [Table1]
), cte2 AS (
-- Add row_number to pull most recent to top
SELECT [RefNumber],
[Action],
[ActionDate],
[DateRank] =
ROW_NUMBER() OVER (PARTITION BY RefNumber
ORDER BY [ActionDate] DESC)
FROM [cte]
)
-- select only the most recent
SELECT *
FROM cte2
WHERE [DateRank] = 1

SELECT RecordID, MaxDate
FROM SourceTable
CROSS APPLY (SELECT MAX(d) MaxDate
FROM (VALUES (date1), (date2), (date3),
(date4), (date5), (date6),
(date7)) AS dates(d)) md

I wrote a custom function to do this:
CREATE FUNCTION [dbo].[MaxOf5]
(
#D1 DateTime,
#D2 DateTime,
#D3 DateTime,
#D4 DateTime,
#D5 DateTime
)
RETURNS DateTime
AS
BEGIN
DECLARE #Result DateTime
SET #Result = COALESCE(#D1, #D2, #D3, #D4, #D5)
IF #D2 IS NOT NULL AND #D2 > #Result SET #Result = #D2
IF #D3 IS NOT NULL AND #D3 > #Result SET #Result = #D3
IF #D4 IS NOT NULL AND #D4 > #Result SET #Result = #D4
IF #D5 IS NOT NULL AND #D5 > #Result SET #Result = #D5
RETURN #Result
END
To call this, and calculated your Action column, this should work:
SELECT
MaxDate,
CASE WHEN MaxDate = FirstVisitedDate THEN 'FirstVisited'
WHEN MaxDate = SecondVisitedDate THEN 'SecondVisited'
WHEN MaxDate = RecoveryDate THEN 'Recovery'
WHEN MaxDate = ActionDate THEN 'Action'
END AS [Action]
FROM (
SELECT
RefNumber,
dbo.MaxOf5(FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate) AS MaxDate,
FirstVisitedDate, SecondVisitedDate, RecoveryDate, ActionDate
FROM table
) AS data
Note that is is possible for more than one of your dates to be tied for the max date. In this case, the order of your WHEN clauses determines which one wins.

Related

How to run Query in loops and counts the number of rows of each loop

I have a query that collects data for me, at the end of it I'm filtering on two dates and I count the number of rows.
FROM TAB
WHERE
(tab.transfer_date < '2019-03-11' AND Real_Updated_date >= '2019-03-11')
ORDER BY transfer_date
Is there a possibility to increase both dates by '1' till '2019-03-20'
and count and print how many rows I had in each day?
Thanks!
Full Query:
WITH TAB AS (
SELECT
[vortex_hvc].[vortex_dbo].material_history.updated_datetime
,[vortex_hvc].[vortex_dbo].material_history.transfer_date
,cast(
case
when [vortex_hvc].[vortex_dbo].material_history.transfer_date = [vortex_hvc].[vortex_dbo].material_history.updated_datetime then getdate()
else [vortex_hvc].[vortex_dbo].material_history.updated_datetime end as datetime
) as Real_Updated_date
FROM [vortex_hvc].[vortex_dbo].[vw_public_material_location]
join [vortex_hvc].[vortex_dbo].[vw_public_material_unit]
on vw_public_material_location.material_name = vw_public_material_unit.unit_number
JOIN [vortex_hvc].[vortex_dbo].[material_history]
ON [vortex_hvc].[vortex_dbo].vw_public_material_location.material_id = [vortex_hvc].[vortex_dbo].material_history.material_id
where
DateDiff(d,[vortex_hvc].[vortex_dbo].material_history.transfer_date, getdate()) < 30
AND
[vortex_hvc].[vortex_dbo].vw_public_material_location.quantity = 1
and
[vortex_hvc].[vortex_dbo].material_history.location_id in ('3492','3500','3981','3493','3504','3497','4140',
'3498', '3496','3627','4378','3512','4376','4542','4379','3802','4517','4410','4182','4758','3499','4897','4239','4820',
'4133','4377','4342','5042','5113','5358','5100','5550','5548','5549','5359',
'5594','5601','5614','5696','5701')
)
select tab.*
FROM TAB
where
(tab.transfer_date < '2019-03-11' ANd Real_Updated_date >= '2019-03-11')
order by transfer_date
You could do something like this:
DECLARE #dateFilter datetime, #enddate datetime
DECLARE #mycounts AS TABLE (mydate datetime, mycount int)
DECLARE #mydata AS TABLE (updated_datetime datetime, transfer_date datetime, real_updated_date datetime)
INSERT INTO #mydata
SELECT
[vortex_hvc].[vortex_dbo].material_history.updated_datetime
,[vortex_hvc].[vortex_dbo].material_history.transfer_date
,cast(
case
when [vortex_hvc].[vortex_dbo].material_history.transfer_date = [vortex_hvc].[vortex_dbo].material_history.updated_datetime then getdate()
else [vortex_hvc].[vortex_dbo].material_history.updated_datetime end as datetime
) as Real_Updated_date
FROM [vortex_hvc].[vortex_dbo].[vw_public_material_location]
join [vortex_hvc].[vortex_dbo].[vw_public_material_unit]
on vw_public_material_location.material_name = vw_public_material_unit.unit_number
JOIN [vortex_hvc].[vortex_dbo].[material_history]
ON [vortex_hvc].[vortex_dbo].vw_public_material_location.material_id = [vortex_hvc].[vortex_dbo].material_history.material_id
where
DateDiff(d,[vortex_hvc].[vortex_dbo].material_history.transfer_date, getdate()) < 30
AND
[vortex_hvc].[vortex_dbo].vw_public_material_location.quantity = 1
and
[vortex_hvc].[vortex_dbo].material_history.location_id in ('3492','3500','3981','3493','3504','3497','4140',
'3498', '3496','3627','4378','3512','4376','4542','4379','3802','4517','4410','4182','4758','3499','4897','4239','4820',
'4133','4377','4342','5042','5113','5358','5100','5550','5548','5549','5359',
'5594','5601','5614','5696','5701')
)
SET #dateFilter = '2019-03-11' --this is the first date used as filter
SET #enddate='2019-03-20' --this is the last one
WHILE #dateFilter <= #enddate
BEGIN
INSERT INTO #mycounts
SELECT #dateFilter, count(*) as mycount FROM #mydata tab
WHERE
(tab.transfer_date < #dateFilter AND Real_Updated_date >= #dateFilter)
SET #dateFilter = DATEADD(day,1,#dateFilter)
END
SELECT * FROM #mycounts
By using DATEADD you are going to be able to filter different months/years as well.

SQL case statement closest to current date

Need help create a case statement to find the closest date from date table. My data: https://imgur.com/hkBu4SA
I basically want to set:
Y flag if it's closest to today's date from a.FROM_EFFDT and is not null.
F if to_effdate is null
else N
WHEN a.FROM_EFFDT < GETDATE() AND (to_effdate) IS NOT NULL THEN 'Y'
WHEN to_effdate IS NULL THEN 'F'
ELSE 'N'
You can use window functions:
(case when row_number() over (order by abs(datediff(day, getdate(), to_effdate)) = 1
then 'Y'
when to_effdate is null then 'F'
else 'N'
end)
You may be able to accomplish it with something like this. Though this isn't bulletproof, you could get duplicates if the closest date is tied.
create table Dates (from_effdt datetime, to_effdt datetime, flag varchar(1))
insert Dates (from_effdt, to_effdt, flag)
values
('2019-03-16', null, '') ,
('2018-06-14', '2019-03-16', '') ,
('2018-05-14', '2018-06-14', '') ,
('2018-01-01', '2018-05-14', '')
select * from Dates
UPDATE Dates
SET flag =
CASE
WHEN from_effdt = (
select top 1 from_effdt
from Dates
order by ABS ( DATEDIFF(day, from_effdt, getdate()) )
)
THEN 'Y'
ELSE
'N'
END
*update, not sure why I created it as an update. This select should do.
SELECT from_effdt, to_effdt,
CASE
WHEN from_effdt = (
select top 1 from_effdt
from Dates
order by ABS ( DATEDIFF(day, from_effdt, getdate()) )
)
THEN 'Y'
ELSE
'N'
END [numberOfDaysAway]
FROM Dates
You can simply do this:
CASE
WHEN from_effdt = (
select from_effdt
from Dates
where abs(datediff(second, from_effdt, getdate()))
= (select min(
abs(datediff(second, from_effdt, getdate()))
)
from Dates)
)
THEN 'Y'
ELSE
'N'
END
ROW_NUMBER() Over (Partition by id order by to_effdt desc)
,id
,from_effdt
,to_effdt
, CASE WHEN (ROW_NUMBER() Over (Partition by id order by to_effdt desc) = 1) THEN ('Y')
WHEN (to_effdt IS NULL) THEN ('F') ELSE ('N') End as flag
from a

Combine multiple queries in 1 return row

I have a query which should return 1 row for each DetectorID. What we currently have is the following:
DECLARE #StartDate datetime SET #StartDate = '2017-12-01 00:00'
DECLARE #EndDate datetime select #EndDate ='2018-01-01 00:00'
DECLARE #Limit1 real SET #Limit1 = 200; DECLARE #AssenLimit1 real SET #AssenLimit1 = 0;
DECLARE #Limit2 real SET #Limit2 = 300; DECLARE #AssenLimit2 real SET #AssenLimit2 = 0;
DECLARE #Limit3 real SET #Limit3 = 350; DECLARE #AssenLimit3 real SET #AssenLimit3 = 0;
DECLARE #Limit4 real SET #Limit4 = 400; DECLARE #AssenLimit4 real SET #AssenLimit4 = 0;
DECLARE #Limit5 real set #Limit5 = 500; DECLARE #AssenLimit5 real SET #AssenLimit5 = 0;
SELECT DetectorID, AVG(ValidWIM) AS 'PI_mean_WIM',
COUNT(ValidWIM) AS 'PI_mean_WIM2',
COUNT(CASE
WHEN ValidWIM > 0.5 THEN ValidWIM ELSE NULL END)
AS 'PI_mean_WIM3'
,AVG((ValidWDD_Left+ValidWDD_Right)/2) AS 'PI_mean_WDD'
,COUNT(ValidWDD_Left) AS 'PI_mean_WDD2'
,COUNT (CASE
WHEN (ValidWDD_Left>0.5 AND ValidWDD_Right>0.5) THEN ValidWDD_Left ELSE NULL END)
AS PI_mean_WDD3
,COUNT(CASE
WHEN AxleLoad IS NOT NULL Then TrainPassageInformationID ELSE NULL END)
AS 'nWheels'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit1 OR PeakForceRight>#Limit1) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>200'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit2 OR PeakForceRight>#Limit2) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>300'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit3 OR PeakForceRight>#Limit3) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>350'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit4 OR PeakForceRight>#Limit4) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>400'
, COUNT(CASE
WHEN (PeakForceLeft > #Limit5 OR PeakForceRight>#Limit5) THEN TrainPassageInformationID ELSE NULL END)
AS 'n>500'
From WheelDamage
where (TimeOfAxle > #StartDate AND TimeOfAxle < #EndDate) and DetectorID in (11,12)
GROUP BY DetectorID
order by DetectorID asc
SELECT DetectorID,
AVG(PeakForceLeft) AS 'NoiseLeft' FROM WheelDamage as t
where PeakForceLeft in (
select top 10 percent PeakForceLeft
from wheeldamage as tt
where tt.WheelDamageID = t.WheelDamageID AND tt.PeakForceLeft <> 0 AND tt.PeakForceLeft IS NOT NULL AND (t.TimeOfAxle > #StartDate AND t.TimeOfAxle < #EndDate)
order by tt.PeakForceLeft asc)
Group By DetectorID
order by DetectorID asc
SELECT DetectorID,
AVG(PeakForceRight) AS 'NoiseRight' FROM WheelDamage as t
where PeakForceLeft in (
select top 10 percent PeakForceRight
from wheeldamage as tt
where tt.WheelDamageID = t.WheelDamageID AND tt.PeakForceRight <> 0 AND tt.PeakForceLeft IS NOT NULL AND (t.TimeOfAxle > #StartDate AND t.TimeOfAxle < #EndDate)
order by tt.PeakForceLeft asc)
Group By DetectorID
order by DetectorID asc
SELECT DetectorId, COUNT (DateTime) AS 'Tags1'
FROM [TagPassage]
WHERE Valid = 1 AND (DateTime > #StartDate AND DateTime < #EndDate)
GROUP by DetectorID
Order by DetectorID asc
SELECT DetectorID, COUNT(CASE
WHEN (TotalWeight=0 OR TotalWeight IS NULL) AND (HasTrainStandStill<>1 OR HasTrainStandStill IS NULL) THEN (TrainPassageInformationID) ELSE NULL END) AS 'notAnalyzed'
, SUM (TotalWeight) AS 'TotalWeight'
FROM TrainPassageInformation
WHERE (Datetime > #StartDate AND Datetime < #EndDate)
Group By DetectorID
order by DetectorID asc
This is returing 5 new rows which I understand. This is because i have 5 select statements. However, I need to know how i can put the bottom 4 select statements in the top one so that it will only return 1 row.
I have tried with Select(Select X xxx). But that gave the error that it is returning more then 1 rows.
The image above is showing the current result. I want the bottom 4 tables to be columns in the first table.
can you just join/left join all the scripts together as table and link by DetectorID, then u can select the columns from the 4 scripts at the bottom to the right.

Query with Join of tables is taking long time to execute 5 min

SELECT
B.AccountBranchID
,B.VoucherNo
,B.BranchName AS BranchName
,B.InvoiceNo
,CONVERT(VARCHAR, B.InvoiceDate, 103) AS InvoiceDate
,CONVERT(VARCHAR, B.VoucherDate, 103) AS VoucherDate
,B.CustomerName
,B.RefID
,LN.AccountName AS LedgerName
,b.SalesPersonName AS SalesPersonName
,LN.LedgerCode
,B.AgentName
,B.ShipperName
,B.Segment
,B.TransactionType
,B.JobNo
,CONVERT(VARCHAR, B.JOBDate, 103) AS JOBDate
,B.MAWBNo
,B.HAWBNo
,B.AccountName
,B.LedgerCode AS AccountLedgerCode
,B.CurrencyCode
,ISNULL(B.Amount, 0) AS Amount
,B.ChargeExRate
,(CASE B.CRDR
WHEN 'CR' THEN (B.ChargeBaseAmount * -1)
ELSE B.ChargeBaseAmount
END) AS ChargeBaseAmount
,(CASE B.CRDR
WHEN 'CR' THEN 'Credit'
ELSE 'Debit'
END) AS CRDR
FROM VW_VoucherTR AS B
INNER JOIN VW_VoucherTR AS LN
ON B.VoucherID = LN.VoucherID
WHERE B.CompanyID = #CompanyID
AND (CASE #Type
WHEN 'I' THEN B.InvoiceDate
ELSE B.VoucherDate
END) BETWEEN ISNULL(#FromDate, (SELECT
FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)
) AND ISNULL(#ToDate, GETDATE())
AND (#Segment IS NULL
OR B.Segment = #Segment)
AND (#BranchMappingID IS NULL
OR B.BranchMappingID = #BranchMappingID)
AND B.VoucherTypeCode IN ('sv')
AND B.IsDeleted = 0
AND (B.GroupName <> 'Sundry Creditors'
AND B.GroupName <> 'Sundry Debtors')
AND LN.GroupName IN ('Sundry Debtors', 'Sundry Creditors')
The subquery in the BETWEEN is probably what is killing you. Have you looked at the execution plan?
BETWEEN ISNULL(#FromDate, (
SELECT FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID
))
AND ISNULL(#ToDate, GETDATE())
What's happening is you are running that query across every row, and by my looks, that's unnecessary because you are only needing static dates there (not anything based on the joined rows.)
Try this:
DECLARE #FromDateActual datetime = ISNULL(#FromDate, (
SELECT FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID
));
DECLARE #ToDateActual datetime = ISNULL(#ToDate, GETDATE());
SELECT B.AccountBranchID
,B.VoucherNo
,B.BranchName AS BranchName
,B.InvoiceNo
,convert(VARCHAR, B.InvoiceDate, 103) AS InvoiceDate
,convert(VARCHAR, B.VoucherDate, 103) AS VoucherDate
,B.CustomerName
,B.RefID
,LN.AccountName AS LedgerName
,b.SalesPersonName AS SalesPersonName
,LN.LedgerCode
,B.AgentName
,B.ShipperName
,B.Segment
,B.TransactionType
,B.JobNo
,convert(VARCHAR, B.JOBDate, 103) AS JOBDate
,B.MAWBNo
,B.HAWBNo
,B.AccountName
,B.LedgerCode AS AccountLedgerCode
,B.CurrencyCode
,ISNULL(B.Amount, 0) AS Amount
,B.ChargeExRate
,(
CASE B.CRDR
WHEN 'CR'
THEN (B.ChargeBaseAmount * - 1)
ELSE B.ChargeBaseAmount
END
) AS ChargeBaseAmount
,(
CASE B.CRDR
WHEN 'CR'
THEN 'Credit'
ELSE 'Debit'
END
) AS CRDR
FROM VW_VoucherTR AS B
INNER JOIN VW_VoucherTR AS LN ON B.VoucherID = LN.VoucherID
WHERE B.CompanyID = #CompanyID
AND (
CASE #Type
WHEN 'I'
THEN B.InvoiceDate
ELSE B.VoucherDate
END
) BETWEEN #FromDateActual
AND #ToDateActual
AND (
#Segment IS NULL
OR B.Segment = #Segment
)
AND (
#BranchMappingID IS NULL
OR B.BranchMappingID = #BranchMappingID
)
AND B.VoucherTypeCode IN ('sv')
AND B.IsDeleted = 0
AND (
B.GroupName <> 'Sundry Creditors'
AND B.GroupName <> 'Sundry Debtors'
)
AND LN.GroupName IN (
'Sundry Debtors'
,'Sundry Creditors'
)
Beyond that you could consider adding non-clustered indexes. The Query Analyzer may even suggest a couple. But you'll want to be careful there, depending on how the data is used and loaded, as too many indexes or large ones can lead to further performance issues in other places (row insertions, page fragmentation, etc).
There could be many reasons for it, but one thing is quite plain. The following part is not sargable.
(CASE #Type
WHEN 'I' THEN B.InvoiceDate
ELSE B.VoucherDate
END) BETWEEN ISNULL(#FromDate, (SELECT
FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)
) AND ISNULL(#ToDate, GETDATE())
Should be rewritten to be sargable, so that indexes can be used.
SELECT #FromDate = ISNULL(#FromDate, (SELECT
TOP 1 FYearStart
FROM Secmst_FinancialYear
WHERE FyearId = #yearID)) )
SELECT #ToDate = ISNULL(#ToDate, GETDATE())
SELECT
...
WHERE
...
AND
((#Type='I' AND B.InvoiceDate BETWEEN #FromDate AND #ToDate)
OR
(#Type<>'I' AND B.VoucherDate BETWEEN #FromDate AND #ToDate))
AND
...
Of course proper indexing is the way how to speed up your query, if no indexes are on InvoiceDate, VoucherDate, etc. then your query will use full table scan instead of index seek and it will be slow.

joining select statements?

I would like to do a inner join in my query but I don´t know how to summarize my two select statements into one query.
This is the first query:
select
Machine
, EventDefinition
, Duration
, sum(Duration) over (partition by 1) As Total
, Duration/sum(Duration) over (partition by 1)*100 AS Distribution
,case when EventCategory < 0.05 Then 'NOT INCL' ELSE 'OK' END AS Under3Min
from (
Select
SystemName AS Machine
, EventDefinition
, EventDate
, EventStartDateTime
, IsNull(EventEndDateTime, GETDATE()) as EventEndDateTime
, Sum(cast(EventEndDateTime - EventStartDateTime as float))*24 as Duration
,Sum(case when CustomEvent = 'without Stop' then cast(EventEndDateTime - EventStartDateTime as float)*24 else 0 end) as EventCategory
FROM tDataCategory
WHERE EventDate >= #StartDateTime
AND EventDate <= #EndDateTime
AND SystemName = '201'
Group BY SystemName, eventdefinition, eventstartdatetime, eventenddatetime, EventDefinition, EventDate, CustomEvent
) as t
WHERE CustomEvent <> 'without Stop'
OR (CustomEvent = 'without Stop' AND t.EventCategory >=0.05)
group by EventDefinition
, Duration
,Machine
,EventCategory
output:
and my second query:
SELECT DataValue = case when Prod = 0 then 0 else ISNULL(100.0 / Prod * Scrap, 0) end,
Value = GoodUnits/TheoreticalUnits *100,
FROM (
Select intervaldate as DateValue, intervalDateWeek as Datum, tsystem.Name as Name, ProductName as Product, teamname as Team,
SUM(case when IssueName in ('A1', 'A2') then calculationUnitsInitial else 0 end) as Scrap,
Sum(case when IssueName = 'Prod' then calculationUnitsInitial else 0 end) as Prod,
SUM(GoodUnits)
As GoodUnits,
SUM(TheoreticalUnits) As TheoreticalUnits,
from tCount inner join tsystem ON tCount.systemid = tsystem.id
where IntervalDate >= dateadd(wk, datediff(wk, 1, getdate()), 0)
and IntervalDate <= dateadd(wk, datediff(wk, 0, getdate()), 0)
AND ((DATEPART(dw, IntervalDate) + ##DATEFIRST) % 7) NOT IN (0,1)
and tsystem.Name = '201'
group by intervaldate, tsystem.Name, intervaldateweek, ProductName, teamname
) as s
output:
I tried it to add in my query two select statements. But if I do this the output is wrong. I really don´t know how I should join this two queries.
I would like to do then this calculation: Distribution * (1 - Value)
Distribution from the first query and Value from the second query
I assume the first and second result set has to be joined based on A.Machine=B.Name
Try like this,
SELECT A.Distribution * (1 - B.Value)
FROM (
SELECT Machine
,EventDefinition
,Duration
,sum(Duration) OVER (PARTITION BY 1) AS Total
,Duration / sum(Duration) OVER (PARTITION BY 1) * 100 AS Distribution
,CASE
WHEN EventCategory < 0.05
THEN 'NOT INCL'
ELSE 'OK'
END AS Under3Min
FROM (
SELECT SystemName AS Machine
,EventDefinition
,EventDate
,EventStartDateTime
,IsNull(EventEndDateTime, GETDATE()) AS EventEndDateTime
,Sum(cast(EventEndDateTime - EventStartDateTime AS FLOAT)) * 24 AS Duration
,Sum(CASE
WHEN CustomEvent = 'without Stop'
THEN cast(EventEndDateTime - EventStartDateTime AS FLOAT) * 24
ELSE 0
END) AS EventCategory
FROM tDataCategory
WHERE EventDate >= #StartDateTime
AND EventDate <= #EndDateTime
AND SystemName = '201'
GROUP BY SystemName
,eventdefinition
,eventstartdatetime
,eventenddatetime
,EventDefinition
,EventDate
,CustomEvent
) AS t
WHERE CustomEvent <> 'without Stop'
OR (
CustomEvent = 'without Stop'
AND t.EventCategory >= 0.05
)
GROUP BY EventDefinition
,Duration
,Machine
,EventCategory
) A
INNER JOIN (
SELECT DataValue = CASE
WHEN Prod = 0
THEN 0
ELSE ISNULL(100.0 / Prod * Scrap, 0)
END
,Value = GoodUnits / TheoreticalUnits * 100
,NAME
FROM (
SELECT intervaldate AS DateValue
,intervalDateWeek AS Datum
,tsystem.NAME AS NAME
,ProductName AS Product
,teamname AS Team
,SUM(CASE
WHEN IssueName IN (
'A1'
,'A2'
)
THEN calculationUnitsInitial
ELSE 0
END) AS Scrap
,Sum(CASE
WHEN IssueName = 'Prod'
THEN calculationUnitsInitial
ELSE 0
END) AS Prod
,SUM(GoodUnits) AS GoodUnits
,SUM(TheoreticalUnits) AS TheoreticalUnits
,
FROM tCount
INNER JOIN tsystem ON tCount.systemid = tsystem.id
WHERE IntervalDate >= dateadd(wk, datediff(wk, 1, getdate()), 0)
AND IntervalDate <= dateadd(wk, datediff(wk, 0, getdate()), 0)
AND ((DATEPART(dw, IntervalDate) + ##DATEFIRST) % 7) NOT IN (
0
,1
)
AND tsystem.NAME = '201'
GROUP BY intervaldate
,tsystem.NAME
,intervaldateweek
,ProductName
,teamname
) AS s
) B ON A.Machine = B.NAME