Multiple Rows to one row - sql

I have one tricky problem. (At least for me) I need to get all the values for the rows with the same AdressNrADR on one row instead of multiple. Is their some way to do this?
SELECT ADR_Adressen.AdressNrADR, CRM_Aufgaben.TerminVon, LAG_Artikel.ArtikelNrLAG,
PRO_Auftraege.Z_R_ckmeldung_Zusatzartikel, CRM_AufgabenLink.MitNrPRO FROM ( ( ( ( ( ( ADR_Adressen
LEFT JOIN PRO_Auftraege ON ADR_Adressen.AdressNrADR = PRO_Auftraege.Kunde)
LEFT JOIN CRM_Aufgaben ON PRO_Auftraege.AuftragNrPRO = CRM_Aufgaben.AuftragNrPRO)
LEFT JOIN CRM_Status ON CRM_Aufgaben.StatusCRM = CRM_Status.StatusCRM)
LEFT JOIN LAG_Artikel ON CRM_Aufgaben.ArtikelNrLAG = LAG_Artikel.ArtikelNrLAG)
LEFT JOIN ADR_GruppenLink ON ADR_Adressen.AdressNrADR = ADR_GruppenLink.AdressNrADR)
LEFT JOIN ADR_Gruppen ON ADR_GruppenLink.GruppeADR = ADR_Gruppen.GruppeADR)
LEFT JOIN CRM_AufgabenLink ON CRM_Aufgaben.AufgabenNrCRM = CRM_AufgabenLink.AufgabenNrCRM
WHERE { d '2020-02-10'}<=CRM_Aufgaben.TerminVon AND { d '2020-02-16'}+1>=CRM_Aufgaben.TerminBis and CRM_AufgabenLink.MitNrPRO != 0 and CRM_Status.StatusCRM = 1 GROUP BY ADR_Adressen.AdressNrADR,CRM_Aufgaben.TerminVon,CRM_Aufgaben.TerminBis, ADR_Adressen.Name, ADR_Adressen.Vorname, LAG_Artikel.ArtikelNrLAG, LAG_Artikel.Bezeichnung1,CRM_AufgabenLink.MitNrPRO,PRO_Auftraege.Z_R_ckmeldung_Zusatzartikel
ORDER BY ADR_Adressen.Name
Output now:
AdressNrADR TerminVon ArtikelNrLAG Z_R_ckmeldung_Zusatzartikel MitNrPRO
13507 2020-02-12 11:00:00.000 7601 7602 2169
13507 2020-02-13 15:00:00.000 7311 NULL 2337
13507 2020-02-14 10:00:00.000 7311 NULL 1028
12955 2020-02-11 08:00:00.000 7311 NULL 1028
12955 2020-02-11 14:00:00.000 3101 NULL 2347
12955 2020-02-13 10:00:00.000 7311 7352 1991
12955 2020-02-13 13:00:00.000 3101 NULL 2347
12955 2020-02-13 14:00:00.000 7311 NULL 1028
10007 2020-02-11 15:00:00.000 7601 7602 1806
10007 2020-02-14 13:00:00.000 7311 NULL 1833
Desired Output:
AdressNrADR TerminVon1 ArtikelNrLAG1 Z_R_ckmeldung_Zusatzartikel1 MitNrPRO1 TerminVon2 ArtikelNrLAG2 Z_R_ckmeldung_Zusatzartikel2 MitNrPRO2 TerminVon3 ArtikelNrLAG3 Z_R_ckmeldung_Zusatzartikel3 MitNrPRO3
13507 2020-02-12 11:00:00.000 7601 7602 2169 2020-02-13 15:00:00.000 7311 NULL 2337 2020-02-14 10:00:00.000 7311 NULL 1028

You can use conditional aggregation and row_number():
with cte as (
<your query here>
)
select AdressNrADR,
max(case when seqnum = 1 then TerminVon end) as TerminVon1,
max(case when seqnum = 1 then ArtikelNrLAG end) as ArtikelNrLAG1,
. . .
max(case when seqnum = 2 then TerminVon end) as TerminVon2,
. . .
from (select cte.*, row_number() over (partition by AdressNrADR order by AdressNrADR) as seqnum
from cte
) t
group by AdressNrADR;

Related

SQL-SERVER Filter By ROW_NUMBER and Another Condition

I have this SQL-SERVER Query:
SELECT t.Id,
t.ClientTemplateFieldId,
t.ClientTemplateFieldOptionId,
t.TextData,
t.NumberData,
t.DateTimeData,
t.TreatmentDate,
t.rn FROM
(
SELECT tfd.Id,
tfd.ClientTemplateFieldId,
tfd.ClientTemplateFieldOptionId,
tfd.TextData,
tfd.NumberData,
tfd.DateTimeData,
t.TreatmentDate,
ROW_NUMBER() OVER (PARTITION BY tfd.ClientTemplateFieldId ORDER BY t.TreatmentDate DESC) as rn
FROM TemplateFieldData tfd
INNER JOIN
Treatment t ON tfd.TreatmentId = t.Id
WHERE tfd.IsDeleted = 0 AND
t.IsDeleted = 0 AND
tfd.ClientId = 2 AND
t.ClientId = 2 AND
t.PatientId = 6003720 AND
tfd.ClientTemplateFieldId IN
(1873,1874,1875,1876)
) AS t
--WHERE CLAUSE...
And this is the table result of the above query:
Id ClientTemplateFieldId ClientTemplateFieldOptionId TextData NumberData DateTimeData TreatmentDate rn
4324 1873 1627 NULL NULL NULL 2021-01-14 09:00:00.000 1
4325 1873 1628 NULL NULL NULL 2021-01-14 09:00:00.000 2
4326 1873 1631 NULL NULL NULL 2021-01-14 09:00:00.000 3
4322 1873 1627 NULL NULL NULL 2021-01-13 09:00:00.000 4
4323 1873 1629 NULL NULL NULL 2021-01-13 09:00:00.000 5
4320 1873 1626 NULL NULL NULL 2021-01-12 22:00:00.000 6
4321 1873 1630 NULL NULL NULL 2021-01-12 22:00:00.000 7
4338 1874 NULL SomeTxt NULL NULL 2021-01-14 09:00:00.000 1
4330 1874 NULL SomeTxt NULL NULL 2021-01-13 09:00:00.000 2
4327 1874 NULL SomeTxt NULL NULL 2021-01-12 22:00:00.000 3
4328 1875 NULL NULL 10.00 NULL 2021-01-12 22:00:00.000 1
4331 1876 1634 NULL NULL NULL 2021-01-13 09:00:00.000 1
4329 1876 1632 NULL NULL NULL 2021-01-12 22:00:00.000 2
What should I put in the Where Clause in order to retrieve all rows with row_number = 1 and
also if there is a row with the same TreatmentDate and ClientTemplateFieldId as of one of the rows where
row_number = 1, I need that row to.
Meaning I need this result:
Id ClientTemplateFieldId ClientTemplateFieldOptionId TextData NumberData DateTimeData TreatmentDate rn
4324 1873 1627 NULL NULL NULL 2021-01-14 09:00:00.000 1
4325 1873 1628 NULL NULL NULL 2021-01-14 09:00:00.000 2
4326 1873 1631 NULL NULL NULL 2021-01-14 09:00:00.000 3
4338 1874 NULL SomeTxt NULL NULL 2021-01-14 09:00:00.000 1
4328 1875 NULL NULL 10.00 NULL 2021-01-12 22:00:00.000 1
4331 1876 1634 NULL NULL NULL 2021-01-13 09:00:00.000 1
You could use MAX() window function instead of ROW_NUMBER() to get all the rows with the latest TreatmentDate for each ClientTemplateFieldId:
SELECT t.Id,
t.ClientTemplateFieldId,
t.ClientTemplateFieldOptionId,
t.TextData,
t.NumberData,
t.DateTimeData,
t.TreatmentDate,
t.rn
FROM (
SELECT tfd.Id,
tfd.ClientTemplateFieldId,
tfd.ClientTemplateFieldOptionId,
tfd.TextData,
tfd.NumberData,
tfd.DateTimeData,
t.TreatmentDate,
ROW_NUMBER() OVER (PARTITION BY tfd.ClientTemplateFieldId ORDER BY t.TreatmentDate DESC) AS rn,
MAX(t.TreatmentDate) OVER (PARTITION BY tfd.ClientTemplateFieldId) AS max_TreatmentDate
FROM TemplateFieldData tfd
INNER JOIN
Treatment t ON tfd.TreatmentId = t.Id
WHERE tfd.IsDeleted = 0 AND
t.IsDeleted = 0 AND
tfd.ClientId = 2 AND
t.ClientId = 2 AND
t.PatientId = 6003720 AND
tfd.ClientTemplateFieldId IN
(1873,1874,1875,1876)
) AS t
WHERE t.TreatmentDate = t.max_TreatmentDate
ROW_NUMBER() is not actually needed but I kept it in my query just in case you want it in the results.
If I assume that this entire query result (without the where condition) is created as a View called T for example, you can do the following:
SELECT *
FROM T
WHERE T.rn = 1
OR EXISTS
(SELECT 1 FROM T as T2
WHERE T2.TreatmentDate = T.TreatmentDate
AND T2.ClientTemplateFieldId = T.ClientTemplateFieldId
AND T.rn != 1
AND T2.rn = 1)

Check if there's an existing record on the day before

I'm trying to check if there's an existing record on the day before the selected schedule date. How do we do this? I tried using LAG(), but I'm having problem when it comes to sorting out the data because of the NULL.
DATEDIFF() won't solve my problem as well because I need to check if there's an existing data on that date, and not -1 the date.
What I want to query if example. Day before 2020-01-02 has recordin and recordout, it should reflect NULL if necessary. Is there a way to do this?
This will be the result.
scheduledate schedulein scheduleout recordin recordout prevrecordin prevrecordout
2020-01-02 08:00:00.0000000 17:00:00.0000000 07:41:12.0000000 17:16:54.0000000 NULL NULL
prevrecordin and prevrecordout will be both NULL since 2020-01-01 is NULL.
This is first table.
badgenumber checktype recordin checkdate
10 I 2019-12-20 07:35:58.000 2019-12-20
10 I 2019-12-21 05:18:14.000 2019-12-21
10 I 2019-12-23 07:35:33.000 2019-12-23
10 I 2019-12-26 07:48:20.000 2019-12-26
10 I 2019-12-27 07:41:03.000 2019-12-27
10 I 2019-12-28 07:35:42.000 2019-12-28
10 I 2020-01-02 07:41:12.000 2020-01-02
10 I 2020-01-03 07:50:12.000 2020-01-03
10 I 2020-01-04 07:41:12.000 2020-01-04
This query is being processed by this.
.....
OUTER APPLY (
SELECT TOP(1) t1.recordin, t1.badgenumber
FROM (SELECT MAX(userinfo.badgenumber) AS badgenumber, MAX(RTRIM(checkinout.checktype)) AS 'checktype',
MIN(checkinout.checktime) as 'recordin', MIN(CONVERT(date,checkinout.checktime)) as checkdate,
MAX(RTRIM(employeemasterfile.employeeidno)) AS 'employeeidno' FROM ((checkinout INNER JOIN userinfo
ON checkinout.userid = userinfo.userid) INNER JOIN employeemasterfile ON userinfo.badgenumber = employeemasterfile.fingerscanno)
INNER JOIN departmentmasterfile ON LEFT(employeemasterfile.employeeidno, 4) = LEFT(departmentmasterfile.departmentcode, 4)
WHERE CONVERT(date,checkinout.checktime) BETWEEN DATEADD(DAY, -1,'2019-12-21') AND DATEADD(DAY, 1,'2020-01-05') and badgenumber = '10'
AND CHECKINOUT.CHECKTYPE = 'I' COLLATE SQL_Latin1_General_CP1_CS_AS GROUP BY userinfo.badgenumber, LEFT(checkinout.checktime,14)) AS t1
WHERE
t1.recordin BETWEEN DATEADD(HOUR,-(t0.noofhoursduty),t0.mergetimeinorig) AND DATEADD(HOUR, (t0.noofhoursduty),t0.mergetimeinorig)
AND t1.badgenumber = t0.fingerscanno
AND t0.schedulename !='REST'
ORDER BY abs(datediff(minute, t0.mergetimeinorig, t1.recordin )) DESC
) t1
This is the second table.
badgenumber checktype recordout checkdate
10 O 2019-12-20 20:41:46.000 2019-12-20
10 O 2019-12-21 14:12:34.000 2019-12-21
10 O 2019-12-23 17:03:44.000 2019-12-23
10 O 2019-12-26 17:05:16.000 2019-12-26
10 O 2019-12-27 17:02:32.000 2019-12-27
10 O 2019-12-28 17:07:38.000 2019-12-28
10 O 2020-01-02 17:16:54.000 2020-01-02
10 O 2020-01-03 17:05:11.000 2020-01-03
10 O 2020-01-04 17:04:42.000 2020-01-04
This is being processed by this query.
OUTER APPLY (
SELECT TOP(1) t2.recordout, t2.badgenumber
FROM (SELECT MAX(userinfo.badgenumber) AS badgenumber, MAX(RTRIM(checkinout.checktype)) AS 'checktype',
MAX(checkinout.checktime) as 'recordout', MAX(CONVERT(date,checkinout.checktime)) as checkdate,
MAX(RTRIM(employeemasterfile.employeeidno)) AS 'employeeidno' FROM ((checkinout INNER JOIN userinfo
ON checkinout.userid = userinfo.userid) INNER JOIN employeemasterfile ON userinfo.badgenumber = employeemasterfile.fingerscanno)
INNER JOIN departmentmasterfile ON LEFT(employeemasterfile.employeeidno, 4) = LEFT(departmentmasterfile.departmentcode, 4)
WHERE CONVERT(date,checkinout.checktime) BETWEEN DATEADD(DAY, -1,'2019-12-21') AND DATEADD(DAY, 1,'2020-01-05') and badgenumber = '10'
AND CHECKINOUT.CHECKTYPE = 'O' COLLATE SQL_Latin1_General_CP1_CS_AS GROUP BY userinfo.badgenumber, LEFT(checkinout.checktime,14)) AS t2
WHERE
t2.recordout BETWEEN DATEADD(HOUR,-(t0.noofhoursduty),t0.mergetimeoutorig) AND DATEADD(HOUR, (t0.noofhoursduty),t0.mergetimeoutorig)
AND t2.badgenumber = t0.fingerscanno
AND t0.schedulename !='REST'
ORDER BY abs(datediff(minute, t0.mergetimeoutorig, t2.recordout )) DESC
) t2
This is the query result.
for t1.recordin, and t2.recordout, scheduledate comes from t0.scheduledate with the corresponding date on the table respectively.
scheduledate schedulein scheduleout recordin recordout
2019-12-21 06:00:00.0000000 14:00:00.0000000 05:18:14.0000000 14:12:34.0000000
2019-12-23 08:00:00.0000000 17:00:00.0000000 07:35:33.0000000 17:03:44.0000000
2019-12-24 08:00:00.0000000 17:00:00.0000000 NULL NULL
2019-12-25 08:00:00.0000000 17:00:00.0000000 NULL NULL
2019-12-26 08:00:00.0000000 17:00:00.0000000 07:48:20.0000000 17:05:16.0000000
2019-12-27 08:00:00.0000000 17:00:00.0000000 07:41:03.0000000 17:02:32.0000000
2019-12-28 08:00:00.0000000 17:00:00.0000000 07:35:42.0000000 17:07:38.0000000
2019-12-30 08:00:00.0000000 17:00:00.0000000 NULL NULL
2019-12-31 08:00:00.0000000 17:00:00.0000000 NULL NULL
2020-01-01 08:00:00.0000000 17:00:00.0000000 NULL NULL
2020-01-02 08:00:00.0000000 17:00:00.0000000 07:41:12.0000000 17:16:54.0000000
2020-01-03 08:00:00.0000000 17:00:00.0000000 07:50:12.0000000 17:05:11.0000000
2020-01-04 08:00:00.0000000 17:00:00.0000000 07:41:12.0000000 17:04:42.0000000
I tried doing CASE WHEN (LAG()) as well, unfortunately I am unable to do it because of the NULL value as well.
What I need to achieve is a new column that will display somewhat like this.
Similar expected result.
scheduledate schedulein scheduleout recordin recordout prevrecordin prevrecordout
21/12/2019 06:00:00 14:00:00 05:18:14 14:12:34 NULL NULL
23/12/2019 08:00:00 17:00:00 07:35:33 17:03:44 05:18:14 14:12:34
24/12/2019 08:00:00 17:00:00 NULL NULL 07:35:33 17:03:44
25/12/2019 08:00:00 17:00:00 NULL NULL NULL NULL
26/12/2019 08:00:00 17:00:00 07:48:20 17:05:16 NULL NULL
27/12/2019 08:00:00 17:00:00 07:41:03 17:02:32 07:48:20 17:05:16
28/12/2019 08:00:00 17:00:00 07:35:42 17:07:38 07:41:03 17:02:32
30/12/2019 08:00:00 17:00:00 NULL NULL 07:35:42 17:07:38
31/12/2019 08:00:00 17:00:00 NULL NULL NULL NULL
01/01/2020 08:00:00 17:00:00 NULL NULL NULL NULL
02/01/2020 08:00:00 17:00:00 07:41:12 17:16:54 NULL NULL
03/01/2020 08:00:00 17:00:00 07:50:12 17:05:11 07:41:12 17:16:54
04/01/2020 08:00:00 17:00:00 07:41:12 17:04:42 07:50:12 17:05:11
Your help would be greatly appreciated. Thank you.
Based on your sample data, I am assuming the following:
At most record per badge per day.
recordin and recordout on the same day.
checktype is irrelevant
You know how to generate the data in the original table.
If so, you can use lag():
select t.*,
(case when datediff(day,
lag(recordin) over (partition by badgenumber order by recordin),
recordin
) <> 1
then null
else lag(recordin) over (partition by badgenumber order by recordin)
end),
(case when datediff(day,
lag(recordin) over (partition by badgenumber order by recordin),
recordin
) <> 1
then null
else lag(recordout) over (partition by badgenumber order by recordin)
end),
from t;
If the above are not true, I would suggest that you ask a new question. Try to simplify the problem. Your rather complex query has nothing to do with the question you are asking, so it doesn't help the question.

SQL: How to get the correct resource time for each time record after removed overlap

I have set of machines used record, and there is more than one work piece used on a machine and sometime each record time period are overlapped. Right now I would get the actual time used on each record after removed overlapped time....but that is difficult to me as a SQL beginner....Hope anyone can give me help...thx
The total used time for CW01 should be 22 hrs and EN01 is 8 hrs after removed ovelap time
Orignal TABLE
operid machine itemid start_time end_time time_used
--------------------------------------------------------------------------------------------------
454 CW01 31 2017-10-16 08:30:00.000 2017-10-16 16:30:00.000 8
456 CW01 33 2017-10-16 13:30:00.000 2017-10-16 18:30:00.000 5
457 CW01 35 2017-10-16 21:30:00.000 2017-10-17 06:30:00.000 9
458 CW01 36 2017-10-16 15:30:00.000 2017-10-16 23:30:00.000 8
460 EN01 70 2017-10-16 08:30:00.000 2017-10-16 10:30:00.000 2
462 EN01 71 2017-10-16 09:30:00.000 2017-10-16 16:30:00.000 7
Desired TABLE
operid machine itemid start_time end_time time_used
--------------------------------------------------------------------------------------------------
454 CW01 31 2017-10-16 08:30:00.000 2017-10-16 16:30:00.000 6.33333
456 CW01 33 2017-10-16 13:30:00.000 2017-10-16 18:30:00.000 2.33333
457 CW01 35 2017-10-16 21:30:00.000 2017-10-17 06:30:00.000 8
458 CW01 36 2017-10-16 15:30:00.000 2017-10-16 23:30:00.000 5.33333
460 EN01 70 2017-10-16 08:30:00.000 2017-10-16 10:30:00.000 1.5
462 EN01 71 2017-10-16 09:30:00.000 2017-10-16 16:30:00.000 6.5
with Q(operid, machine, tm) as(
-- split rows to time points (start(3), end(4), intersect time (1,2))
select distinct A.operid,A.machine,
case N when 1 then (case when A.start_time>B.start_time
then A.start_time else B.start_time end)
when 2 then (case when A.end_time < B.end_time
then A.end_time else B.end_time end)
when 3 then A.start_time
else A.end_time
end
from TabD A
cross join (select 1 N union all select 2 union all select 3 union all select 4) N
left join TabD B
on B.machine=A.machine and B.operid!=A.operid
and B.start_time<A.end_time and B.end_time>A.start_time and N.N in(1,2)
)
select operid, machine, sum(time_len)
from (
select X.operid, A.machine, s_tm, e_tm,
datediff(second, s_tm, e_tm)/3600.0/count(1) time_len
from (
-- join time points to intervals
select operid, machine, tm e_tm,
lag(tm) over(partition by machine,operid order by tm) s_tm
from Q
where Q.tm is not null
) X,
TabD A -- join source rows for interval of time for count it
where s_tm is not null
and A.start_time<X.e_tm and A.end_time>X.s_tm
and A.machine=X.machine
group by X.operid, A.machine, s_tm, e_tm
) Y
group by operid, machine
Example on sqlfiddle.com

SQL - Use Value until End, then Use last value

I have written a query that gives me Growth of an Estimate from 2015 - 2016.
I am using a Variable Called EBIT, EBIT with Date_Year = 2015 has data for Date_Month 2013-12-31 to 2016-12-31 while EBIT With Date_Year = 2016 has data for Date_Month 2013-12-31 to 2017-06-30.
Is there a way to do the exakt same as I've done but after 2016-12-31 use the last value of EBIT (2015) instead and hence keep going?
In the Code below EBIT (2015) & EBIT (2016) is just to illustrate the numbers.
The table furthest down is the optimal table that I am trying to get but I can't understand how I can get there ...
As you can see the Current Output stops at 2016-12-31 while the Desired Output assumes that EBIT (2015) = 936808 after it has no more values and EBIT (2016) keeps going until data for it ends.
I am thinking of maybe incorporating something like the code below yet I can't have a Max function inside of a Sum(Case when) and I also think this might not pick the maximum n2.EBIT for the max(Date_Month_Id) with same Date_Year_ID etc.
(
SUM(case when n2.Date_Month_Id < (Select Max(Date_Month_Id) From EBIT where Date_Year_ID in (2015))
Then n2.EBIT else max(n2.EBIT) end
)
/
SUM(n1.EBIT) - 1) AS 'EBIT Growth 2015-2016'
Current Query:
SELECT
m1.date_Month,
SUM(n2.EBIT) As 'EBIT (2015)',
SUM(n1.EBIT) AS 'EBIT (2016)',
SUM(n2.EBIT) /
SUM(n1.EBIT) - 1 AS 'EBIT Growth 2015-2016'
FROM EBIT AS n1
INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id
INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id
INNER JOIN EBIT AS n2
INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id
INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 and y1.date_year = 2015 AND y2.date_year = 2016
GROUP BY m1.date_month
ORDER BY m1.Date_Month ASC;
Current Output:
date_Month EBIT (2015) EBIT (2016) EBIT Growth 2015-2016
2013-12-31 2198051.670 2053514.548 0.070385
2014-01-31 1112047.668 1045523.283 0.063627
2014-02-28 1109221.007 1043085.024 0.063404
2014-03-31 1118112.429 1047602.842 0.067305
2014-04-30 1117082.270 1044455.198 0.069535
2014-05-31 1122019.824 1045228.639 0.073468
2014-06-30 1130536.274 1053516.159 0.073107
2014-07-31 1135838.665 1055882.605 0.075724
2014-08-31 1138886.938 1056331.236 0.078153
2014-09-30 1147685.937 1064254.322 0.078394
2014-10-31 1126437.959 1040798.042 0.082282
2014-11-30 1116292.468 1029127.634 0.084697
2014-12-31 1111509.880 1020233.204 0.089466
2015-01-31 1109692.378 1011895.933 0.096646
2015-02-28 1103494.875 1000990.365 0.102403
2015-03-31 1099507.246 996252.094 0.103643
2015-04-30 1094694.816 997653.412 0.097269
2015-05-31 1103352.777 1007836.533 0.094773
2015-06-30 1098103.559 1004344.223 0.093353
2015-07-31 1081689.371 994391.939 0.087789
2015-08-31 1064033.692 979809.245 0.085960
2015-09-30 1041604.341 971746.514 0.071888
2015-10-31 1044583.652 979410.989 0.066542
2015-11-30 1049158.666 989746.574 0.060027
2015-12-31 1022646.632 969556.360 0.054757
2016-01-31 990592.876 968797.454 0.022497
2016-02-29 961009.086 934777.852 0.028061
2016-03-31 942917.628 933858.404 0.009700
2016-04-30 937784.980 931500.111 0.006747
2016-05-31 941049.211 928974.727 0.012997
2016-06-30 930969.603 929102.681 0.002009
2016-07-31 926670.277 928979.675 -0.002486
2016-08-31 927442.570 929233.754 -0.001928
2016-09-30 924658.701 930248.793 -0.006010
2016-10-31 925569.857 930250.547 -0.005032
2016-11-30 938894.794 930156.559 0.009394
2016-12-31 936808.419 929592.092 0.007762
Desired Output (and the % Increase but I know how to implement that code):
date_month EBIT(2015) EBIT(2016)
31/12/2013 2198052 2053515
31/01/2014 1112048 1045523
28/02/2014 1109221 1043085
31/03/2014 1118112 1047603
30/04/2014 1117082 1044455
31/05/2014 1122020 1045229
30/06/2014 1130536 1053516
31/07/2014 1135839 1055883
31/08/2014 1138887 1056331
30/09/2014 1147686 1064254
31/10/2014 1126438 1040798
30/11/2014 1116292 1029128
31/12/2014 1111510 1020233
31/01/2015 1109692 1011896
28/02/2015 1103495 1000990
31/03/2015 1099507 996252
30/04/2015 1094695 997653
31/05/2015 1103353 1007837
30/06/2015 1098104 1004344
31/07/2015 1081689 994392
31/08/2015 1064034 979809
30/09/2015 1041604 971747
31/10/2015 1044584 979411
30/11/2015 1049159 989747
31/12/2015 1022647 969556
31/01/2016 990593 968797
29/02/2016 961009 934778
31/03/2016 942918 933858
30/04/2016 937785 931500
31/05/2016 941049 928975
30/06/2016 930970 929103
31/07/2016 926670 928980
31/08/2016 927443 929234
30/09/2016 924659 930249
31/10/2016 925570 930251
30/11/2016 938895 930157
31/12/2016 936808 929592
31/01/2017 936808 942461
28/02/2017 936808 936845
31/03/2017 936808 940401
30/04/2017 936808 933644
31/05/2017 936808 942218
Ps. I'm using Microsoft SQL Server Management Studio
---- EDIT ---------
Thanks to assistance I've been able to get the code below that yields almost exactly what I need. however if I keep the "AND y1.date_year = y2.date_Year + 1 condition I don't get values for n2.EBIT past 2017-01-31. If I remove it the query sums up way to many values for some reason ...
... do you know any work around?
Reworked Code:
SELECT
m1.date_Month,
isnull(sum(case when y2.date_year = 2015 then n2.EBIT end),Max(innern2.december_value)) as 'EBIT 2015',
sum(case when y1.date_year = 2016 then n1.EBIT end) AS 'EBIT (2016)',
sum(case when y1.date_year = 2016 then n1.EBIT end) /
isnull(sum(case when y2.date_year = 2015 then n2.EBIT end),SUM(innern2.december_value)) - 1 AS 'EBIT Growth 2015-2016'
FROM EBIT AS n1
INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id
INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id
LEFT JOIN EBIT AS n2
INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id
INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month
LEFT JOIN
(
SELECT maxn2.date_year_id, SUM(maxn2.EBIT) as december_value
FROM EBIT maxn2
Inner join Date_Month As M on M.Date_Month_Id = maxn2.Date_Month_Id
inner join Date_Year as Y on Y.Date_Year_Id = maxn2.Date_Year_Id
WHERE Month(Date_Month) = 12 and year(Date_Month) = 2016
GROUP BY maxn2.date_year_id
) as innern2 on innern2.date_year_id = n1.date_year_id - 1
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 AND y1.date_year = y2.date_year + 1
and n2.Date_Month_Id >= (Select Min(E.Date_Month_Id) from EBIT as E inner join Date_Year as Y on Y.Date_Year_Id = E.Date_Year_Id Where Y.Date_Year = 2016)
GROUP BY m1.date_month
ORDER BY m1.Date_Month asc;
OutPut with Constraint mentioned:
date_Month EBIT 2015 EBIT (2016)
2013-12-31 2053514.548 2198051.670
2014-01-31 1045523.283 1112047.668
2014-02-28 1043085.024 1109221.007
2014-03-31 1047602.842 1118112.429
2014-04-30 1044455.198 1117082.270
2014-05-31 1045228.639 1122019.824
2014-06-30 1053516.159 1130536.274
2014-07-31 1055882.605 1135838.665
2014-08-31 1056331.236 1138886.938
2014-09-30 1064254.322 1147685.937
2014-10-31 1040798.042 1126437.959
2014-11-30 1029127.634 1116292.468
2014-12-31 1020233.204 1111509.880
2015-01-31 1011895.933 1109692.378
2015-02-28 1000990.365 1103494.875
2015-03-31 996252.094 1099507.246
2015-04-30 997653.412 1094694.816
2015-05-31 1007836.533 1103352.777
2015-06-30 1004344.223 1098103.559
2015-07-31 994391.939 1081689.371
2015-08-31 979809.245 1064033.692
2015-09-30 971746.514 1041604.341
2015-10-31 979410.989 1044583.652
2015-11-30 989746.574 1049158.666
2015-12-31 969556.360 1022646.632
2016-01-31 968797.454 990592.876
2016-02-29 934777.852 961009.086
2016-03-31 933858.404 942917.628
2016-04-30 931500.111 937784.980
2016-05-31 928974.727 941049.211
2016-06-30 929102.681 930969.603
2016-07-31 928979.675 926670.277
2016-08-31 929233.754 927442.570
2016-09-30 930248.793 924658.701
2016-10-31 930250.547 925569.857
2016-11-30 930156.559 938894.794
2016-12-31 929592.092 936808.419
2017-01-31 942617.388 NULL
2017-02-28 942617.388 NULL
2017-03-31 942617.388 NULL
2017-04-30 942617.388 NULL
2017-05-31 942617.388 NULL
Output with suggested constraint "AND y1.date_Year = 2016":
date_Month EBIT 2015 EBIT (2016)
2013-12-31 2053514.548 8781104.520
2014-01-31 1045523.283 3330912.804
2014-02-28 1043085.024 3322433.491
2014-03-31 1047602.842 3349059.127
2014-04-30 1044455.198 3346078.340
2014-05-31 1045228.639 3360889.672
2014-06-30 1053516.159 3385242.192
2014-07-31 1055882.605 3401244.625
2014-08-31 1056331.236 3410616.294
2014-09-30 1064254.322 3436856.111
2014-10-31 1040798.042 3373162.267
2014-11-30 1029127.634 3342757.174
2014-12-31 1020233.204 4363552.086
2015-01-31 1011895.933 4384691.285
2015-02-28 1000990.365 4376807.747
2015-03-31 996252.094 4375725.598
2015-04-30 997653.412 4357711.561
2015-05-31 1007836.533 4392712.780
2015-06-30 1004344.223 4373955.988
2015-07-31 994391.939 4314820.563
2015-08-31 979809.245 4247412.535
2015-09-30 971746.514 4151358.468
2015-10-31 979410.989 4161422.299
2015-11-30 989746.574 4179141.525
2015-12-31 969556.360 4077629.132
2016-01-31 968797.454 2970088.034
2016-02-29 934777.852 2881375.640
2016-03-31 933858.404 2827941.356
2016-04-30 931500.111 2815130.846
2016-05-31 928974.727 2824951.723
2016-06-30 929102.681 2794527.987
2016-07-31 928979.675 2783688.491
2016-08-31 929233.754 2785958.962
2016-09-30 930248.793 2783949.407
2016-10-31 930250.547 2787387.285
2016-11-30 930156.559 2827684.912
2016-12-31 929592.092 2822043.195
2017-01-31 930177.105 1884922.522
2017-02-28 930177.105 1873690.578
2017-03-31 930177.105 1880802.312
2017-04-30 930177.105 1867287.280
2017-05-31 930177.105 1884436.230
Output without "and y1.date_year = y2.date_year - 1 constraint:
date_Month EBIT 2015 EBIT (2016)
2013-12-31 4255200.364 8781104.520
2014-01-31 3237430.013 3330912.804
2014-02-28 3201517.162 3322433.491
2014-03-31 3190328.126 3349059.127
2014-04-30 3176902.028 3346078.340
2014-05-31 3171643.267 3360889.672
2014-06-30 3172452.363 3385242.192
2014-07-31 3169541.043 3401244.625
2014-08-31 3170477.020 3410616.294
2014-09-30 3192395.112 3436856.111
2014-10-31 3120825.630 3373162.267
2014-11-30 3082544.372 3342757.174
2014-12-31 4002614.551 4363552.086
2015-01-31 3997360.080 4384691.285
2015-02-28 3968359.858 4376807.747
2015-03-31 3965754.869 4375725.598
2015-04-30 3971742.802 4357711.561
2015-05-31 4010919.518 4392712.780
2015-06-30 3997415.185 4373955.988
2015-07-31 3966592.901 4314820.563
2015-08-31 3911382.409 4247412.535
2015-09-30 3871093.275 4151358.468
2015-10-31 3900314.386 4161422.299
2015-11-30 3938511.747 4179141.525
2015-12-31 3862780.776 4077629.132
2016-01-31 2903039.552 2970088.034
2016-02-29 2801085.898 2881375.640
2016-03-31 2798222.402 2827941.356
2016-04-30 2794500.333 2815130.846
2016-05-31 2787967.181 2824951.723
2016-06-30 2788351.043 2794527.987
2016-07-31 2787982.025 2783688.491
2016-08-31 2788744.262 2785958.962
2016-09-30 2790746.379 2783949.407
2016-10-31 2790751.641 2787387.285
2016-11-30 2790469.677 2827684.912
2016-12-31 2789361.289 2822043.195
2017-01-31 942617.388 1884922.522
2017-02-28 942617.388 1873690.578
2017-03-31 942617.388 1880802.312
2017-04-30 942617.388 1867287.280
2017-05-31 942617.388 1884436.230
Have you considered a left join?
SELECT
m1.date_Month,
isnull(SUM(n2.EBIT),936808) As 'EBIT (2015)',
SUM(n1.EBIT) AS 'EBIT (2016)',
isnull(SUM(n2.EBIT),936808) /
SUM(n1.EBIT) - 1 AS 'EBIT Growth 2015-2016'
FROM EBIT AS n1
INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id
INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id
LEFT JOIN EBIT AS n2
INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id
INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id
ON n1.Company_Id = n2.company_Id AND m1.date_month = m2.date_month
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 and y1.date_year = 2015 AND y2.date_year = 2016
GROUP BY m1.date_month
ORDER BY m1.Date_Month ASC;
Also, comparing you output column names, I was thinking your where clause may have mixed the years, so should be:
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 and y1.date_year = 2016 AND y2.date_year = 2015
EDIT---------
Add in a inline table to get the december EBIT from previous year
SELECT
m1.date_Month,
isnull(SUM(n2.EBIT),MAX(innern2.december_value)) As 'EBIT (2015)',
SUM(n1.EBIT) AS 'EBIT (2016)',
isnull(SUM(n2.EBIT),MAX(innern2.december_value)) /
SUM(n1.EBIT) - 1 AS 'EBIT Growth 2015-2016'
FROM EBIT AS n1
INNER JOIN date_year AS y1 ON y1.date_year_id = n1.date_year_id
INNER JOIN date_month AS m1 ON m1.date_month_id = n1.date_month_id
LEFT JOIN EBIT AS n2
INNER JOIN date_year AS y2 ON y2.date_year_id = n2.date_year_id
INNER JOIN date_month AS m2 ON m2.date_month_id = n2.date_month_id
ON n1.Company_Id = n2.company_Id
AND m1.date_month = m2.date_month
AND year(y1.date_year) = year(y2.date_year) - 1
LEFT JOIN
(
SELECT year(Y.date_year) as [year], SUM(maxn2.EBIT) as december_value
FROM EBIT maxn2
Inner join Date_Month As M on M.Date_Month_Id = maxn2.Date_Month_Id
inner join Date_Year as Y on Y.Date_Year_Id = maxn2.Date_Year_Id
WHERE Month(M.Date_Month) = 12
GROUP BY year(Y.date_year)
) as innern2 on innern2.[year] = year(y1.date_year) - 1
WHERE n1.EBIT <> 0 AND n2.EBIT <> 0 and year(y1.date_year) >= 2016
GROUP BY m1.date_month
ORDER BY m1.Date_Month ASC;
To check this approach, if you run this part from the inner query, you should get a list of years and the value of the december EBIT for that year:
SELECT year(Y.date_year) as [year], SUM(maxn2.EBIT) as december_value
FROM EBIT maxn2
Inner join Date_Month As M on M.Date_Month_Id = maxn2.Date_Month_Id
inner join Date_Year as Y on Y.Date_Year_Id = maxn2.Date_Year_Id
WHERE Month(M.Date_Month) = 12
GROUP BY year(Y.date_year)

Distinct query for SQL Server needed

I am pulling data with this query in SQL Server
SELECT DISTINCT
DOC.TPID,
DOC.TYPE,
DOC.DOCNO,
O211.PONO,
H210.INVDATE,
H210.INVNO,
H210.EQPMTINIT,
H210.EQPMTNO,
D214.DESTIMATED,
D214.DACTUAL,
DOC.CDATETIME
FROM [databasename].[dbo].[DOC]
JOIN [databasename].[dbo].[IN_211_HDR] H211 ON DOC.[TRANNO] = H211.TRANNO
JOIN [databasename].[dbo].[IN_211_ORD] O211 ON H211.TRANNO = O211.TRANNO
JOIN [databasename].[dbo].[IN_210_HDR] H210 ON DOCNO = H210.BOLNO
JOIN [databasename].[dbo].[IN_214_HDR] H214 ON H211.BOLNO = H214.SHPID
JOIN [databasename].[dbo].[IN_214_DTL] D214 ON H214.TRANNO = D214.TRANNO
WHERE
[TPID] = 'DSV' AND doc.[STATUSERP] = ''
ORDER BY
CDATETIME DESC
This will return the following result set.
O211.PONO D214.DESTIMATED
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-04-20 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-02 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-03 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8204126 106824 2014-05-27 00:00:00.000 US01271338 CCLU 4481776 2014-05-18 00:00:00.000 NULL 2014-04-10 15:00:10.000
DSV 211 STAD8203444 106843 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106843 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106847 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 106847 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 108380 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-04-17 00:00:00.000 NULL 2014-04-10 08:03:14.000
DSV 211 STAD8203444 108380 2014-05-21 00:00:00.000 US01267372 TGHU 4732265 2014-05-05 00:00:00.000 NULL 2014-04-10 08:03:14.000
I need to have it so that it only returns rows with a unique O211.PONO. The only difference between those rows is the date but I need to only return one row for each unique O211.PONO number. It should take the one with the latest date in the D214.DESTIMATED field.
The easiest way is with row_number():
with t as (
<your query here without the order by>
)
select t.*
from (select t.*,
row_number() over (partition by PONO order by DESTIMATED desc) as seqnum
from t
) t
where seqnum = 1;