SQL - Use Value until End, then Use last value - sql

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)

Related

Multiple Rows to one row

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;

Add value from one table to another, depending on dates

how can i add a value from one table to another. There is a attribute(VALUE) that depends on the date from both tables. So VALUE has to get add to TABLE 1 between the corret dates.
Example:
Table 1
ID BEGIN END MODEL DOLLAR
1 2014-01-01 2014-01-31 Z5 500
1 2014-02-01 2014-02-28 Z5 500
1 2014-03-01 2014-03-31 Z5 672
1 2014-03-11 2014-03-31 Z3 158
1 2014-04-01 2014-04-30 Z3 023
....
1 2016-12-01 2016-12-31 Z2 400
1 2017-01-01 2017-01-31 Z4 433
1 2017-02-01 2017-02-28 Z9 065
Table 2
ID BEGIN END VALUE
1 2014-01-01 2017-01-01 3
1 2017-01-01 2999-12-31 9
This is a small example from 2 big tables. I discovered that the join works, but sometimes some errors occurs(because sum(dollar) isnt 100% right). Do i have to add something in the join clause?
select * from t1
INNER JOIN t2 on
(
t1.id = t2.id
and t1.begin between t2.beginn and t1.begin
and t1.end between t1.end and t2.end
)
DESIRED RESULT
ID BEGIN END MODEL DOLLAR VALUE
1 2014-01-01 2014-01-31 Z5 500 3
1 2014-02-01 2014-02-28 Z5 500 3
1 2014-03-01 2014-03-31 Z5 672 3
1 2014-03-11 2014-03-31 Z3 158 3
1 2014-04-01 2014-04-30 Z3 023 3
...
1 2016-12-01 2016-12-31 Z2 400 3
1 2017-01-01 2017-01-31 Z4 433 9
1 2017-02-01 2017-02-28 Z9 065 9
If you want any overlap, then:
select *
from t1 join
t2
on t1.id = t2.id and
t2.begin <= t1.end
t2.end >= t1.begin;
If you want full overlap then:
select *
from t1 join
t2
on t1.id = t2.id and
t2.begin <= t1.begin
t2.end >= t1.end;
Note: Because you are dealing with time ranges, you may get multiple matches in the result set for a single time frame.

aligning tables with different dates

I have two tables, called tblDaily and tblWeekly.
So tblDaily contains daily data & tblWeekly contains data that is stored every friday.
So obviously it is easy to join the daily table to the weekly table when the date in the daily data is a friday.
My question is what is the best way to join when the date is not a friday. So for example say I had the date 2018-05-09 (Wednesday) I would like to join it on the previous friday (2018-05-04). What is the optimal way of doing this?
I read about a calendar table, would that be the correct way to go? Although I'm not sure how that would work in this case?
tblDaily
date val
2018-04-30 2 'mon
2018-05-01 3 'tues
2018-05-02 3 'wed
2018-05-03 3 'thurs
2018-05-04 3 'fri
2018-05-07 2 'mon
2018-05-08 3 'tues
2018-05-09 3 'wed
2018-05-10 3 'thurs
2018-05-11 3 'fri
2018-05-14 3 'mon
tblWeekly
date val
2018-05-04 2 'fri
2018-05-11 3 'fri
This might work:
SELECT
[dailydate] = D.[date],
[dailyval] = D.[val],
[weeklydate] = W.[date],
[weeklyval] = W.[val]
FROM
[tblDaily] AS D
OUTER APPLY (SELECT TOP (1) _W.*
FROM [tblWeekly] AS _W
WHERE _W.[date] <= D.[date]
ORDER BY _W.[date] DESC) AS W;
This query produces the following results:
dailydate dailyval weeklydate weeklyval
2018-04-30 2 NULL NULL
2018-05-01 3 NULL NULL
2018-05-02 3 NULL NULL
2018-05-03 3 NULL NULL
2018-05-04 3 2018-05-04 2
2018-05-07 2 2018-05-04 2
2018-05-08 3 2018-05-04 2
2018-05-09 3 2018-05-04 2
2018-05-10 3 2018-05-04 2
2018-05-11 3 2018-05-11 3
2018-05-14 3 2018-05-11 3
Try something like this:
select * from tblDaily a join tblWeekly b on a.date1= dateadd(day,-5,b.date2)
Try this simple join:
select *
from tblDaily [d]
--first condition in join is to match firdays exactly
left join tblWeekly [w] on [w].[date] = [d].[date] or
--here you are joining fridays from tblWeekly to last friday before the date in tblDaily
[w].[date] = dateadd(day, -datepart(weekday, [d].[date]) - 1, [d].[date])
Here is SQL fiddle.

SQL Server : compare rows, exclude from results when some values are the same

I have the following SQL Server query problem.
If there is a row where Issue_DATE = as Maturity_Date in another row, and if both rows have the same ID and Amount USD, then none of these rows should be displayed.
Here is a simplified version of my table:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2010-01-01 00:00:00.000 2015-12-01 00:00:00.000 5000
1 2010-01-01 00:00:00.000 2001-09-19 00:00:00.000 700
2 2014-04-09 00:00:00.000 2019-04-09 00:00:00.000 400
1 2015-12-01 00:00:00.000 2016-12-31 00:00:00.000 5000
5 2015-02-24 00:00:00.000 2015-02-24 00:00:00.000 8000
4 2012-11-29 00:00:00.000 2015-11-29 00:00:00.000 10000
3 2015-01-21 00:00:00.000 2018-01-21 00:00:00.000 17500
2 2015-02-02 00:00:00.000 2015-12-05 00:00:00.000 12000
1 2015-01-12 00:00:00.000 2018-01-12 00:00:00.000 18000
2 2015-12-05 00:00:00.000 2016-01-10 00:00:00.000 12000
Result should be:
ID ISSUE_DATE MATURITY_DATE AMOUNT_USD
1 2010-01-01 00:00:00.000 2001-09-19 00:00:00.000 700
2 2014-04-09 00:00:00.000 2019-04-09 00:00:00.000 400
5 2015-02-24 00:00:00.000 2015-02-24 00:00:00.000 8000
4 2012-11-29 00:00:00.000 2015-11-29 00:00:00.000 10000
3 2015-01-21 00:00:00.000 2018-01-21 00:00:00.000 17500
1 2015-01-12 00:00:00.000 2018-01-12 00:00:00.000 18000
I tried with self join, but I do not get right result.
Thanks in advance!
Can you try something like this? 'not exists' is the way of doing it.
select * from table t1 where not exists (select 'x' from table t2 where t1.issue_date = t2.maturity_date and t1.amount_usd=t2.amount_usd and t1.id = t2.id)
I'd think about making subquery of all the dupes and then eliminating them from the first table like so:
select t1.ID
, t1.ISSUE_DATE
, t1.MATURITY_DATE
, t1.AMOUNT_USD
FROM
t1
LEFT JOIN
(select a.ID
, a.ISSUE_DATE
, a.MATURITY_DATE
, a.AMOUNT_USD
FROM
t1 a
INNER JOIN
ti b
) dupes
on
t1.ID = dupes.ID
WHERE dupes.ID IS NULL;

SQL Server query join several tables

I have a query that I don't think should be that hard to make, however, I've spent a lot of time on it now and still can't get it the way I want, so I hope someone here can help me.
Basically, I need to create a report that will give a value for each month, for each area. However, not all areas deliver data each month; in that case the view should return NULL for that month and area. So, the view need to look something like this:
Month Area Value
2012-08-01 Area1 2
2012-08-01 Area2 3
2012-09-01 Area1 3
2012-09-01 Area2 NULL
My data table looks something like this
Date Area Value
2012-08-01 Area1 2
2012-08-01 Area2 3
2012-09-01 Area1 3 -- Notice that Area2 is not present for September here
I have a table with all the available areas
Furthermore, I have created a table-valued function that returns all dates from a given date until now.
For example this statement
SELECT * FROM Periods_Months('2012-01-01')
would return 8 records like:
DateValue Year Month YearMonth
2012-01-01 00:00:00.000 2012 1 20121
2012-02-01 00:00:00.000 2012 2 20122
2012-03-01 00:00:00.000 2012 3 20123
2012-04-01 00:00:00.000 2012 4 20124
2012-05-01 00:00:00.000 2012 5 20125
2012-06-01 00:00:00.000 2012 6 20126
2012-07-01 00:00:00.000 2012 7 20127
2012-08-01 00:00:00.000 2012 8 20128
Based on the suggestions, my query now looks like this:
WITH months AS (
SELECT DateValue, YearMonth FROM Periods_Months('2011-01-01')
)
select m.DateValue
,CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,m.DateValue)+1,0)) AS Date) AS DateReported -- Get last day in month
,ResponseTime AS Value
,g.ExternalId
from GISDB.dbo.GisObjects g
CROSS JOIN months m
LEFT OUTER JOIN
( -- SELECT data from data table, grouped by area and month
SELECT dbo.YearMonth(CloseDate) AS YearMonth
,MAX(CloseDate) AS LastDate
,GisObjectId
,SUM(DATEDIFF(HH,RegDate,CloseDate)) AS ResponseTime -- calculate response time between start and end data (the value we need)
FROM DataTable
WHERE CloseDate IS NOT NULL
AND GisObjectId IS NOT NULL
GROUP BY GisObjectId, dbo.YearMonth(CloseDate) -- group by area and month
) c
ON g.ObjectId = c.GisObjectId AND c.YearMonth = m.YearMonth
WHERE g.CompanyId = 3 AND g.ObjectTypeId = 1 -- reduce the GIS objects that we compare to
ORDER BY m.DateValue, g.ObjectId
But the result is this (Value is always NULL):
DateValue DateReported Value ExternalId
2011-01-01 00:00:00.000 31-01-2011 NULL 9994
2011-01-01 00:00:00.000 31-01-2011 NULL 9993
2011-01-01 00:00:00.000 31-01-2011 NULL 9992
2011-01-01 00:00:00.000 31-01-2011 NULL 9991
2011-01-01 00:00:00.000 31-01-2011 NULL 2339
2011-01-01 00:00:00.000 31-01-2011 NULL 2338
2011-01-01 00:00:00.000 31-01-2011 NULL 2337
2011-01-01 00:00:00.000 31-01-2011 NULL 2336
2011-01-01 00:00:00.000 31-01-2011 NULL 2335
2011-01-01 00:00:00.000 31-01-2011 NULL 2334
2011-01-01 00:00:00.000 31-01-2011 NULL 2327
2011-01-01 00:00:00.000 31-01-2011 NULL 2326
2011-01-01 00:00:00.000 31-01-2011 NULL 2325
2011-01-01 00:00:00.000 31-01-2011 NULL 2324
2011-01-01 00:00:00.000 31-01-2011 NULL 2323
2011-01-01 00:00:00.000 31-01-2011 NULL 2322
etc.
I suppose you have a table with all your areas, which I call area_table.
WITH month_table AS (
SELECT dateValue FROM Periods_Months('2012-01-01')
)
select * from area_table
CROSS JOIN month_table
LEFT OUTER JOIN myValueTable
ON area_table.name = myValueTable.area
AND myValueTable.date = left(convert(varchar(30),month_table.dateValue,120),10)
ORDER BY myValueTable.Month, myValueTable.area
Suppose Areas is your table for all available areas, t - is your data table:
SELECT pm.dateValue,Ar.Area, t.value
FROM Periods_Months('2012-01-01') pm, Areas ar
left join t on (pm.dateValue=t.Date) and (ar.Area=t.Area)
order by pm.DateValue,ar.Area