SQL Get distinct tax rate form a tax table - sql

I am optimistic that some clever SQL author can tweak my query to give the results I am looking for. I have to extract the current tax rates for a state and distinct tax type (PST/QST/GST/HST) There is usually PST/GST or HST per state. Looking at the data table below I need to get the tax 'rate' for the distinct value of 'Shortname', 'name', and 'Effective Date'.
The desired result is this table:
EffectiveDate Rate ShortName name
2016-01-01 0.050000 AB GST
2013-04-01 0.050000 BC GST
2013-04-01 0.070000 BC PST
2013-07-01 0.050000 MB GST
2013-07-01 0.080000 MB PST
2016-07-01 0.150000 NB HST
2016-07-01 0.150000 NL HST
2016-01-01 0.150000 NS HST
2016-01-01 0.050000 NT GST
2016-01-01 0.050000 NU GST
2015-04-01 0.130000 ON HST
2016-10-01 0.150000 PE HST
2013-01-01 0.050000 QC GST
2017-03-01 0.099750 QC QST
2016-01-01 0.050000 SK GST
2017-03-01 0.060000 SK PST
2009-02-01 0.050000 YT GST
My query so far:
SELECT --TaxRates.ID, --TaxRates.StateId, TaxRateDetails.id,
TaxRateDetails.EffectiveDate, TaxRateDetails.Rate,--TaxRateDetails.TaxRateId,
States.ShortName, TaxImpositionTypes.name -- DISTINCT Name,states.ShortName, TaxRateDetails.Id,TaxImpositionTypeDetailId
FROM dbo.TaxRates
join dbo.TaxRateDetails ON TaxRateDetails.TaxRateId = TaxRates.Id
INNER JOIN States ON dbo.TaxRates.StateId = States.Id AND States.IsActive =1
INNER JOIN TaxImpositionTypeDetails ON TaxRateDetails.TaxImpositionTypeDetailId = TaxImpositionTypeDetails.Id
INNER JOIN TaxImpositionTypes ON dbo.TaxImpositionTypeDetails.TaxImpositionTypeId = TaxImpositionTypes.Id
WHERE EffectiveDate < CURRENT_TIMESTAMP
order BY ShortName
This source table created by this query is as follows:
EffectiveDate Rate ShortName name
2016-01-01 0.050000 AB GST
2009-02-01 0.050000 AB GST
2013-04-01 0.050000 BC GST
2013-04-01 0.070000 BC PST
2013-04-01 0.050000 BC GST
2013-04-01 0.070000 BC PST
2013-07-01 0.050000 MB GST
2013-07-01 0.080000 MB PST
2010-07-01 0.130000 NB HST
2016-07-01 0.150000 NB HST
2010-07-01 0.130000 NB HST
2009-02-01 13.000000 NL HST
2016-07-01 0.150000 NL HST
2010-07-01 0.130000 NL HST
2016-01-01 0.150000 NS HST
2010-07-01 0.150000 NS HST
2016-01-01 0.050000 NT GST
2009-02-01 0.050000 NT GST
2016-01-01 0.050000 NU GST
2009-02-01 0.050000 NU GST
2010-07-01 0.130000 ON HST
2009-02-01 0.050000 ON HST
2009-02-01 0.080000 ON PST
2010-03-01 0.130000 ON HST
2015-04-01 0.130000 ON HST
2015-04-01 0.000100 ON PST
2009-02-01 13.000000 PE HST
2013-04-01 0.140000 PE HST
2016-10-01 0.150000 PE HST
2013-01-01 0.050000 QC GST
2013-01-01 0.010000 QC QST
2012-01-01 0.050000 QC GST
2012-01-01 0.095000 QC QST
2017-03-01 0.099750 QC QST
2016-01-01 0.050000 SK GST
2016-01-01 0.050000 SK PST
2009-02-01 0.050000 SK GST
2009-02-01 0.050000 SK PST
2017-03-01 0.060000 SK PST
2009-02-01 0.050000 YT GST

If I understand the question correctly, we could assign a row number to each unique pairing of shortname and name order that pairing by effective date descending so the highest date is first. Then we only display row 1 of each unique pairing of shortname and name .
WITH CTE AS (
SELECT TaxRateDetails.EffectiveDate
, TaxRateDetails.Rate
, States.ShortName
, TaxImpositionTypes.name
, Row_number() over (partition by States.ShortName,TaxImpositionTypes.name ORDER BY TaxRateDetails.EffectiveDate DESC) RN
FROM dbo.TaxRates
INNER JOIN dbo.TaxRateDetails
ON TaxRateDetails.TaxRateId = TaxRates.Id
INNER JOIN States
ON dbo.TaxRates.StateId = States.Id
AND States.IsActive =1
INNER JOIN TaxImpositionTypeDetails
ON TaxRateDetails.TaxImpositionTypeDetailId = TaxImpositionTypeDetails.Id
INNER JOIN TaxImpositionTypes
ON dbo.TaxImpositionTypeDetails.TaxImpositionTypeId = TaxImpositionTypes.Id
WHERE EffectiveDate < CURRENT_TIMESTAMP)
SELECT * FROM CTE where RN = 1

Related

get end dates from list of start dates in sql

I have a sql query that brings back a list of references (products) that were at a specific status and an effective date. Unfortunately when one product moves to a different status the system doesn't put an end date in, so I am wanting to generate the end date, based on the effective date and sequence number. Is this possible?
Product Status EffectiveDate Enddate SeqNo
10 *UC 2017-10-02 00:00:00.000 NULL 8590
584 UC 2017-02-28 00:00:00.000 NULL 8380
584 APA 2017-07-07 00:00:00.000 NULL 8620
584 APA3 2017-08-10 00:00:00.000 NULL 8630
902 *UC 2017-10-13 00:00:00.000 NULL 8590
902 APA 2017-10-13 00:00:00.000 NULL 8620
1017 *UC 2017-09-01 00:00:00.000 NULL 8590
1017 APA 2017-10-10 00:00:00.000 NULL 8620
SO I would want to return the following...
Product Status EffectiveDate EndDate SeqNo
10 *UC 2017-10-02 00:00:00.000 NULL 8590
584 UC 2017-02-28 00:00:00.000 2017-07-07 00:00:00.000 8380
584 APA 2017-07-07 00:00:00.000 2017-08-10 00:00:00.000 8620
584 APA3 2017-08-10 00:00:00.000 NULL 8630
902 *UC 2017-10-13 00:00:00.000 2017-10-13 00:00:00.000 8590
902 APA 2017-10-13 00:00:00.000 NULL 8620
1017 *UC 2017-09-01 00:00:00.000 2017-10-10 00:00:00.000 8590
1017 APA 2017-10-10 00:00:00.000 NULL 8620
Many thanks.
You can use lead() :
select t.*, lead(EffectiveDate) over (partition by product order by SeqNo) as EndDate
from table t;
However, lead() starts from version 2012 +, so you can use apply instead :
select t.*, t1.EffectiveDate as EndDate
from table t outer apply
(select top (1) t1.*
from table t1
where t1.product = t.product and t1.SeqNo > t.SeqNo
order by t1.SeqNo
) t1;

PostgreSQL: How do I join two tables based on same start and end time (timestamp without time zone)?

Okay, I came across this relevant question but it is slightly different than my case.
Problem
I have two similar type of tables in my PostgreSQL 9.5 database tbl1 and tbl2 both containing 1,274 rows. The structure and layout of table 1 is as follows:
Table 1:
id (integer) start_time end_time my_val1 (numeric)
51 1994-09-26 16:50:00 1994-10-29 13:30:00 3.7
52 1994-10-29 13:30:00 1994-11-27 12:30:00 2.4
53 1994-11-27 12:30:00 1994-12-29 09:25:00 7.6
54 1994-12-29 09:25:00 1994-12-31 23:59:59 2.9
54 1995-01-01 00:00:00 1995-02-05 13:50:00 2.9
55 1995-02-05 13:50:00 1995-03-12 11:10:00 1.6
56 1995-03-12 11:10:00 1995-04-11 09:05:00 2.2
171 1994-10-29 16:15:00 1994-11-27 19:10:00 6.9
172 1994-11-27 19:10:00 1994-12-29 11:40:00 4.2
173 1994-12-29 11:40:00 1994-12-31 23:59:59 6.7
173 1995-01-01 00:00:00 1995-02-05 15:30:00 6.7
174 1995-02-05 15:30:00 1995-03-12 09:45:00 3.2
175 1995-03-12 09:45:00 1995-04-11 11:30:00 1.2
176 1995-04-11 11:30:00 1995-05-11 15:30:00 2.7
321 1994-09-26 14:40:00 1994-10-30 14:30:00 0.2
322 1994-10-30 14:30:00 1994-11-27 14:45:00 7.8
323 1994-11-27 14:45:00 1994-12-29 14:20:00 4.6
324 1994-12-29 14:20:00 1994-12-31 23:59:59 4.1
324 1995-01-01 00:00:00 1995-02-05 14:35:00 4.1
325 1995-02-05 14:35:00 1995-03-12 11:30:00 8.2
326 1995-03-12 11:30:00 1995-04-11 09:45:00 1.2
.....
In some rows, start_time and end_time may look similar but whole time window may not be equal. For example,
id (integer) start_time end_time my_val1 (numeric)
54 1994-12-29 09:25:00 1994-12-31 23:59:59 2.9
173 1994-12-29 11:40:00 1994-12-31 23:59:59 6.7
Start_time and end_time are timestamp without time zone. The start_time and end_time have to be in one year window thus whenever there was a change of year from 1994 to 1995 then that row was divided into two rows therefore, there are repeating IDs in the column id. Table 2 tbl2 contains the similar start_time and end_time (timestamp without time zone) and column my_val2 (numeric). For each row in table 1 I need to join corresponding row of table 2 where start_time and end_time are similar.
What I have tried,
Select
a.id,
a.start_time, a.end_time,
a.my_val1,
b.my_val2
from tbl1 a
left join tbl2 b on
b.start_time = a.start_time
order by a.id;
The query returned 3,802 rows which is not desired. The desired result is 1,274 rows of table 1 joined with my_val2. I am aware of Postgres Distinct on clause but I need to keep all repeating ids of tbl1 and only need to join my_val2 of tbl2. Do I need to use Postgres Window function here. Can someone suggest that how to join these two tables?
why you don't add to the ON part the condition
ON b.start_time = a.start_time AND a.id = b.id
For each row in table 1 I need to join corresponding row of table 2
where start_time and end_time are similar.
SQL query should include end_time
SELECT a.id,
a.start_time,
a.end_time,
a.my_val1,
b.my_val2
FROM tbl1 a
LEFT JOIN tbl2 b
ON b.start_time = a.start_time
AND b.end_time = a.end_time
ORDER BY a.id;

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)

change the output

Sorry I am new to sql world could this statement be checkin time different with checkout time and remove checkinorout from the statement as you well see :
SELECT
USERINFO.Badgenumber AS USERID,
CHECKINOUT.CHECKTIME AS Checkin,
CHECKINOUT.CHECKTIME AS Checkout,
Machines.MachineAlias,
CHECKINOUT.checkinorout
FROM CHECKINOUT
INNER JOIN USERINFO ON CHECKINOUT.USERID = USERINFO.USERID
INNER JOIN Machines ON CHECKINOUT.SENSORID = Machines.MachineNumber
WHERE (CHECKINOUT.CHECKTIME > '2014-09-25 00:00:00.000')
order by checkin
Output:
USERID Checkin Checkout Machines checkinorout
32 2014-09-25 09:12:57.000 2014-09-25 09:12:57.000 HQ Checkin
32 2014-09-25 12:58:51.000 2014-09-25 12:58:51.000 HQ CheckOut
32 2014-09-26 18:03:33.000 2014-09-26 18:03:33.000 HQ Checkin
32 2014-09-26 22:03:11.000 2014-09-26 22:03:11.000 HQ CheckOut
32 2014-09-27 12:57:55.000 2014-09-27 12:57:55.000 HQ Checkin
32 2014-09-27 17:01:32.000 2014-09-27 17:01:32.000 HQ CheckOut
32 2014-09-28 13:05:03.000 2014-09-28 13:05:03.000 HQ Checkin
32 2014-09-28 17:35:29.000 2014-09-28 17:35:29.000 HQ CheckOut
32 2014-09-29 09:18:12.000 2014-09-29 09:18:12.000 HQ Checkin
32 2014-09-29 18:10:43.000 2014-09-29 18:10:43.000 HQ CheckOut
32 2014-09-30 09:12:13.000 2014-09-30 09:12:13.000 HQ Checkin
I need the output be like this
USERID Checkin Checkout Machines
32 2014-09-25 09:12:57.000 2014-09-25 12:58:51.000 HQ
32 2014-09-26 18:03:33.000 2014-09-26 22:03:11.000 HQ
32 2014-09-27 12:57:55.000 2014-09-27 17:01:32.000 HQ
32 2014-09-28 13:05:03.000 2014-09-28 17:35:29.000 HQ
32 2014-09-29 09:18:12.000 2014-09-29 18:10:43.000 HQ
Thanks MR #sgeddes but when i edit your statement to have a result
with cte as (
select *,
row_number() over (partition by userid, checkinorout order by CHECKTIME) rn
from CHECKINOUT
)
select userid,
max(case when checkinorout = 'checkin' then CHECKTIME end) checkin,
max(case when checkinorout = 'checkout' then CHECKTIME end) checkout
from cte where USERID=15 and CHECKTIME between '2014-9-21 00:00:00.000' and '2014-10-25 00:00:00.000'
group by userid , rn
userid checkin checkout
15 NULL 2014-09-21 18:50:24.000
15 NULL 2014-09-22 18:06:15.000
15 NULL 2014-09-23 18:01:30.000
15 NULL 2014-09-24 16:52:36.000
15 NULL 2014-09-25 12:58:51.000
15 NULL 2014-09-26 22:03:11.000
15 NULL 2014-09-27 17:01:32.000
15 NULL 2014-09-28 17:35:29.000
15 NULL 2014-09-29 18:10:43.000
15 NULL 2014-09-30 18:11:19.000
15 NULL 2014-10-01 17:52:49.000
15 NULL 2014-10-12 20:13:10.000
15 2014-09-21 10:17:24.000 2014-10-13 22:13:11.000
15 2014-09-22 09:18:29.000 2014-10-14 21:49:28.000
15 2014-09-23 09:10:15.000 2014-10-15 10:14:09.000
15 2014-09-24 09:43:27.000 2014-10-16 17:55:06.000
15 2014-09-25 09:12:57.000 2014-10-17 23:17:00.000
15 2014-09-26 18:03:33.000 2014-10-20 12:38:22.000
15 2014-09-27 12:57:55.000 2014-10-21 07:31:39.000
15 2014-09-28 13:05:03.000 2014-10-22 05:51:47.000
15 2014-09-29 09:18:12.000 2014-10-24 11:26:06.000
15 2014-09-30 09:12:13.000 NULL
15 2014-10-01 10:16:59.000 NULL
15 2014-10-02 10:13:52.000 NULL
15 2014-10-03 00:59:18.000 NULL
15 2014-10-11 22:07:06.000 NULL
15 2014-10-12 09:58:34.000 NULL
15 2014-10-13 05:09:34.000 NULL
15 2014-10-14 11:42:58.000 NULL
15 2014-10-15 04:48:27.000 NULL
15 2014-10-15 15:49:06.000 NULL
15 2014-10-16 09:14:21.000 NULL
15 2014-10-16 21:14:18.000 NULL
15 2014-10-17 00:59:57.000 NULL
15 2014-10-18 17:42:26.000 NULL
15 2014-10-20 01:22:01.000 NULL
15 2014-10-21 01:24:30.000 NULL
15 2014-10-22 00:10:34.000 NULL
15 2014-10-23 20:01:02.000 NULL
15 2014-10-24 01:08:51.000 NULL
and i need it to be
userid checkin checkout
15 2014-09-21 10:17:24.000 2014-09-21 18:50:24.000
15 2014-09-22 09:18:29.000 2014-09-22 18:06:15.000
15 2014-09-23 09:10:15.000 2014-09-23 18:01:30.000
15 2014-09-24 09:43:27.000 2014-09-24 16:52:36.000
15 2014-09-25 09:12:57.000 2014-09-25 12:58:51.000
15 2014-09-26 18:03:33.000 2014-09-26 22:03:11.000
15 2014-09-27 12:57:55.000 2014-09-27 17:01:32.000
Thanks Mr #slavoo
what i have when i try ....
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkout,
checkingOut.time AS Checkin,
m.MachineAlias
FROM CHECKINOUT c
INNER JOIN USERINFO u ON c.USERID = u.USERID
INNER JOIN Machines m ON c.SENSORID = m.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME between '2014-10-19 00:00:00.000' and '2014-10-27 00:00:00.000' )
and u.Badgenumber=660
AND c.checkinorout = 'Checkin'
AND checkingOut.time is not null
order by checkingOut.time
The output:
USERID Checkout Checkin MachineAlias
660 2014-10-19 01:56:47.000 2014-10-19 17:27:41.000 Branch4
660 2014-10-20 02:00:14.000 2014-10-20 17:39:35.000 Branch4
660 2014-10-21 01:55:49.000 2014-10-21 16:57:22.000 Branch4
660 2014-10-22 01:59:23.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-23 16:59:34.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-24 16:58:36.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-25 01:56:47.000 2014-10-25 16:48:29.000 Branch4
and i need it to be
USERID Checkout Checkin MachineAlias
660 2014-10-20 02:00:14.000 2014-10-19 17:27:41.000 Branch4
660 2014-10-21 01:55:49.000 2014-10-20 17:39:35.000 Branch4
660 2014-10-22 01:59:23.000 2014-10-21 16:57:22.000 Branch4
660 Null 2014-10-23 16:59:34.000 Branch4
660 2014-10-25 01:56:47.000 2014-10-24 16:58:36.000 Branch4
660 2014-10-26 00:55:35.000 2014-10-25 16:48:29.000 Branch4
and this is the table i read from it
select USERID ,CHECKTIME,checkinorout from CHECKINOUT where USERID=80 and CHECKTIME between '2014-10-19 00:00:00.000' and '2014-10-27 00:00:00.000'
order by CHECKTIME
and this is the full transaction for this user
80 2014-10-19 01:56:47.000 Checkin
80 2014-10-19 17:27:41.000 CheckOut
80 2014-10-20 02:00:14.000 Checkin
80 2014-10-20 17:39:35.000 CheckOut
80 2014-10-21 01:55:49.000 Checkin
80 2014-10-21 16:57:22.000 CheckOut
80 2014-10-22 01:59:23.000 Checkin
80 2014-10-23 16:59:34.000 Checkin
80 2014-10-24 16:58:36.000 Checkin
80 2014-10-25 01:56:47.000 Checkin
80 2014-10-25 16:48:29.000 CheckOut
80 2014-10-26 00:55:35.000 Checkin
for your note i have script its update the check in or out in checkinorout column
to know this report be finger print check in and check out report
and if he found no check in leave it Null and if he found the check out null leave it null ( this employ have shift check in 5:00:00 pm and check out 2:00:00 am ) ; .
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkin,
checkingOut.time AS Checkout,
m.MachineAlias
FROM CHECKINOUT c
INNER JOIN users u ON c.USERID = u.USERID
INNER JOIN Machines m ON c.SENSORID = m.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
AND CAST(c.CHECKTIME as DATE) = CAST(c2.CHECKTIME as DATE)
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME > '2014-09-25 00:00:00.000')
AND c.checkinorout = 'Checkin'
order by checkin
SQL Fiddle
SQL Fiddle after update
Or this:
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkin,
checkingOut.time AS Checkout,
Machines.MachineAlias
FROM CHECKINOUT c
INNER JOIN users u ON c.USERID = u.USERID
INNER JOIN Machines ON c.SENSORID = Machines.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
AND NOT EXISTS (SELECT * FROM CHECKINOUT c3
WHERE c3.checkinorout = 'Checkin'
AND c3.USERID = c2.USERID
AND c3.SENSORID = c2.SENSORID
AND c3.CHECKTIME > c.CHECKTIME
AND c3.CHECKTIME < c2.CHECKTIME)
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME > '2014-09-25 00:00:00.000')
AND c.checkinorout = 'Checkin'
order by checkin
SqlFiddle
You can use ROW_NUMBER() to establish a grouping between your checkins and checkouts. Then you need to pivot your results -- you can use MAX with CASE to do that:
Here's a simplified version using a common table expression:
with cte as (
select *,
row_number() over (partition by userid, checkinorout order by checkin) rn
from results
)
select userid,
max(case when checkinorout = 'checkin' then checkin end) checkin,
max(case when checkinorout = 'checkout' then checkout end) checkout,
machines
from cte
group by userid, machines, rn
SQL Fiddle Demo
Edit, given your comments, can you not just use a HAVING clause to remove the NULL records?
having max(case when checkinorout = 'checkin' then checkin end) is not null
and max(case when checkinorout = 'checkout' then checkout end) is not null
Updated Fiddle

joining monthly values with daily values in sql

I have daily values in one table and monthly values in another table. I need to use the values of the monthly table and calculate them on a daily basis.
basically, monthly factor * daily factor -- for each day
thanks!
I have a table like this:
2010-12-31 00:00:00.000 28.3
2010-09-30 00:00:00.000 64.1
2010-06-30 00:00:00.000 66.15
2010-03-31 00:00:00.000 12.54
and a table like this :
2010-12-31 00:00:00.000 98.1
2010-12-30 00:00:00.000 97.61
2010-12-29 00:00:00.000 99.03
2010-12-28 00:00:00.000 97.7
2010-12-27 00:00:00.000 96.87
2010-12-23 00:00:00.000 97.44
2010-12-22 00:00:00.000 97.76
2010-12-21 00:00:00.000 96.63
2010-12-20 00:00:00.000 95.47
2010-12-17 00:00:00.000 95.2
2010-12-16 00:00:00.000 94.84
2010-12-15 00:00:00.000 94.8
2010-12-14 00:00:00.000 94.1
2010-12-13 00:00:00.000 93.88
2010-12-10 00:00:00.000 93.04
2010-12-09 00:00:00.000 91.07
2010-12-08 00:00:00.000 90.89
2010-12-07 00:00:00.000 92.72
2010-12-06 00:00:00.000 93.05
2010-12-03 00:00:00.000 91.74
2010-12-02 00:00:00.000 90.74
2010-12-01 00:00:00.000 90.25
I need to take the value for the quarter and multiply it buy all the days in the quarter by the daily value
You could try:
SELECT dt.day, dt.factor*mt.factor AS daily_factor
FROM daily_table dt INNER JOIN month_table mt
ON YEAR(dt.day) = YEAR(mt.day)
AND FLOOR((MONTH(dt.day)-1)/3) = FLOOR((MONTH(mt.day)-1)/3)
ORDER BY dt.day
or (as suggested by #Andriy)
SELECT dt.day, dt.factor*mt.factor AS daily_factor
FROM daily_table dt INNER JOIN month_table mt
ON YEAR(dt.day) = YEAR(mt.day)
AND DATEPART(QUARTER, dt.day) = DATEPART(QUARTER, mt.day)
ORDER BY dt.day