I will provide examples and code where I can. Assume everything except [CycleStart] and [CycleEnd] datatypes are Varchar, I'm not too fussed about this at this stage.
Table A consists of the following RAW sample data:
+-------+---------+----------------+------------+------------+
| JobID | JobName | CycleDesc | CycleStart | CycleEnd |
+-------+---------+----------------+------------+------------+
| 10003 | Run1 | January 2019 | 31/12/2018 | 31/12/2018 |
| 10005 | Run2 | December 2018 | 31/12/2017 | 31/11/2018 |
| 10006 | Run3 | March 2019 | 31/12/2018 | 31/02/2019 |
| 10007 | Run4 | September 2019 | 31/12/2018 | 31/09/2019 |
| 10008 | Run5 | November 2019 | 31/12/2018 | 31/10/2019 |
+-------+---------+----------------+------------+------------+
Table B consists of the following sample data and the code used to generate this data is below:
+-------+---------+---------+
| JobID | PeriodID | Entity |
+-------+---------+---------+
| 10003 | 202101 | XYZ1 |
| 10003 | 202112 | XYZ2 |
| 10007 | 202008 | XYZ3 |
| 10007 | 202003 | XYZ4 |
| 10008 | 201904 | XYZ5 |
+-------+----------+--------+
Declare #Counter3 INT
SELECT #Counter3=1
WHILE #Counter3 <= 1000
BEGIN
INSERT INTO [dbo].[TableB]
SELECT
FLOOR(RAND()*(33979-1+1))+1 [JobID]
,CAST(ROUND(((2021 - 2019 -1) * RAND() + 2020), 0) AS VARCHAR) + RIGHT('0'+CAST(FLOOR(RAND()*(12-1+1))+1 AS VARCHAR),2) [PeriodID]
,FLOOR(RAND()*(23396-1+1))+1 [Entity]
The issue lies within Table B column [PeriodID]. This column represents an ID generated from [CycleStart] in Table A e.g. 31/12/2018 = 201812 (YYYYMM).
What I want to show in Table B is a Period ID for each Job ID but show EACH month + 30 years ahead of the [CycleStart] date. Example table of what I am looking to achieve:
+-------+---------+---------+
| JobID | PeriodID | Entity |
+-------+---------+---------+
| 10006 | 201812 | XYZ1 |
| 10006 | 201901 | XYZ2 |
| 10006 | 201902 | XYZ3 |
| 10006 | 201903 | XYZ4 |
| 10006 | 201904 | XYZ5 |
| 10006 | 201905 | XYZ5 |
| 10006 | 201906 | XYZ5 |
| 10006 | 201907 | XYZ5 |
| ... | +30yrs | ... |
| 10006 | 204812 | XYZ5 |
+-------+----------+--------+
How can I achieve this? Currently I am just randomly generating IDs which is not related to the [CycleStart] date and therefore just skewing my data but this is the only way I can think of doing it.
The best way is to create a calendar table / date dimension. You can use this table to solve this issue, and reuse it for other problems later. (Search online for some examples on how to build one).
If you have this table then you only need to join this table and that's it.
e.g.
INSERT INTO TableB ( JobID , PeriodID)
SELECT DISTINCT A.JobID , D.TheYear * 100 + D.TheMonth
FROM tableA A
JOIN myDateTable D
ON D.TheDate BETWEEN CONVERT(date , A.CycleStart , 103) AND DATEADD(YEAR,30, CONVERT(date , A.CycleStart , 103));
I have two tables, the first one is dbo.formula
Id | Poste | Calculation | Montant
---+--------+-------------+--------
1 | Achats | 3801%+381% | .....
2 | Tva | 446%-445% | ....
3 | Tiers | 411%+401% | ....
The second table is dbo.value
Compte | Solde
--------+-------
380000 | 400.00
380100 | 500.00
381100 | 200.00
381200 | 100.00
4456600 | 100.00
4455400 | 150.00
I need to be the result in the first table in field Montant like
800.00
50.00
I tried a request but it changes only the 3 beginning compute.
Join the tables on your conditions and aggregate:
select f.ID, f.Poste, sum(v.Solde) total
from formula f inner join value v
on charindex('+' + left(v.Compte, 3) + '%', '+' + f.Calculation) > 0
group by f.ID, f.Poste
See the demo.
Results:
> ID | Poste | total
> -: | :----- | :------
> 1 | Achats | 1200.00
> 2 | Tva | 250.00
I am trying to formulate a query in SQL Server where:
Date | Name | Amount | AmountX
------------+---------+--------+-------
2010-01-01 | Test | 0 | 0
2010-02-01 | Test | 0 | 0
2010-03-01 | Test | 0 | 0
2011-01-01 | Test | 62.61 | 63.86
2011-02-01 | Test | 62.61 | 63.86
2011-03-01 | Test | 62.61 | 63.86
2012-01-01 | Test | 62.61 | 65.14
2012-02-01 | Test | 62.61 | 65.14
2012-03-01 | Test | 62.61 | 65.14
2013-01-01 | Test | 62.61 | 66.44
2013-02-01 | Test | 62.61 | 66.44
2013-03-01 | Test | 62.61 | 66.44
2014-01-01 | Test | 62.61 | 67.77
2014-02-01 | Test | 62.61 | 67.77
2014-03-01 | Test | 62.61 | 67.77
2015-01-01 | Test | 0 | 0
2015-02-01 | Test | 0 | 0
2015-03-01 | Test | 0 | 0
2016-01-01 | Test | 67.95 | 69.31
2016-02-01 | Test | 67.95 | 69.31
2016-03-01 | Test | 67.95 | 69.31
2017-01-01 | Test | 67.95 | 70.70
2017-02-01 | Test | 67.95 | 70.70
2017-03-01 | Test | 67.95 | 70.70
2018-01-01 | Test | 67.95 | 72.11
2018-02-01 | Test | 67.95 | 72.11
2018-03-01 | Test | 67.95 | 72.11
2019-01-01 | Test | 67.95 | 73.55
2019-02-01 | Test | 67.95 | 73.55
2019-03-01 | Test | 67.95 | 73.55
The Date, Name and Amount columns come from the table.
I need to create a query to include to AmountX column based on the Date grouping. The Amount and a factor of 2% for calculation.
Year 2010 can be ignored because the Amount values are 0s.
For the year 2011, the Amount values are none 0s which is 62.61. I need to multiply that by 1.02 giving 63.86, for the whole year and display it in the AmountX column.
Now for the year 2012, it will be calculated 63.86 for previous year X 1.02 = 65.14.
So for 2013, it will be 64.14 X 1.02 = 66.44.
And for 2014, it will be 66.44 X 1.02 = 67.77.
Is this doable?
Any help is greatly appreciated.
RS..
I think you want:
select t.*,
(amount * power(1.02, year(date) - 2010)) as amountX
from t;
I want to calculate a new value for the new column based on other columns in T-SQL.
My data is look like this:
Each row represents one person in one day.
The WorkHours is calculated based on the Portion column:
Round(FF.Portion * 7.4, 3) AS WorkHours
I want to calculate a percentage of hours which people not have been at work in relation to the TOTAL workhours for day for each school. For example if 10 people work full hour in one school for one day, it gives 74 working hours and if one person have been sick that day it will give (7,4 % 74 * 100) which is 10% (the WorkHours is calculated based on Portion column)
In your comment you state Peter had 6 hours on 1/1/2017 as "seek" but it was actually 7.4. With that in mind, we can calculate your results as follows:
declare #table table (Name varchar(16), Date date, School char(2), FreedayCode int, Freeday varchar(64), Portion decimal (6,4))
insert into #table
values
('Mike','20170101','AA',-1,'AtWork',1),
('Mike','20170201','AA',1,'Seek',1),
('Ali','20170101','BB',-1,'AtWork',0.94594),
('Ali','20170201','BB',-1,'AtWork',0.94594),
('Sara','20170101','CC',2,'holiday',1),
('Sara','20170201','CC',1,'Seek',1),
('Peter','20170101','AA',1,'Seek',1),
('Peter','20170201','AA',1,'Seek',1),
('Nina','20170101','AA',-1,'AtWork',0.81081),
('Nina','20170201','AA',-1,'AtWork',0.81081)
select
Name
,Date
,School
,FreeDayCode
,Freeday,Portion
,NewColumn = sum(case when Freeday <> 'AtWork' then Round(Portion * 7.4,3) else 0 end) over (partition by Date, School) / sum(Round(Portion * 7.4,3)) over (partition by Date, School)
from
#table
order by
Date
,School
RETURNS
+-------+------------+--------+-------------+---------+---------+-----------+
| Name | Date | School | FreeDayCode | Freeday | Portion | NewColumn |
+-------+------------+--------+-------------+---------+---------+-----------+
| Mike | 2017-01-01 | AA | -1 | AtWork | 1.0000 | 0.355769 |
| Peter | 2017-01-01 | AA | 1 | Seek | 1.0000 | 0.355769 |
| Nina | 2017-01-01 | AA | -1 | AtWork | 0.8108 | 0.355769 |
| Ali | 2017-01-01 | BB | -1 | AtWork | 0.9459 | 0.000000 |
| Sara | 2017-01-01 | CC | 2 | holiday | 1.0000 | 1.000000 |
| Peter | 2017-02-01 | AA | 1 | Seek | 1.0000 | 0.711538 |
| Mike | 2017-02-01 | AA | 1 | Seek | 1.0000 | 0.711538 |
| Nina | 2017-02-01 | AA | -1 | AtWork | 0.8108 | 0.711538 |
| Ali | 2017-02-01 | BB | -1 | AtWork | 0.9459 | 0.000000 |
| Sara | 2017-02-01 | CC | 1 | Seek | 1.0000 | 1.000000 |
+-------+------------+--------+-------------+---------+---------+-----------+
How can I apply the moving average in temporal database.
My data includes temperature and I want to apply moving average for every 15 records.
You can fire query as below
marc=# SELECT entity, name, salary, start_date,
avg(salary) OVER (ORDER BY entity, start_date
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
FROM salary;
entity | name | salary | start_date | avg
-----------+-----------+---------+---------------+----------------------
Accounting | millicent | 850.00 | 2006-01-01 | 825.0000000000000000
Accounting | jack | 800.00 | 2010-05-01 | 916.6666666666666667
R&D | tom | 1100.00 | 2005-01-01 | 966.6666666666666667
R&D | john | 1000.00 | 2008-07-01 | 933.3333333333333333
R&D | maria | 700.00 | 2009-01-01 | 733.3333333333333333
R&D | kevin | 500.00 | 2009-05-01 | 633.3333333333333333
R&D | marc | 700.00 | 2010-02-15 | 600.0000000000000000
WITH moving_avrag AS (
SELECT 0 AS [lag] UNION ALL
SELECT 1 AS [lag] UNION ALL
SELECT 2 AS [lag] UNION ALL
SELECT 3 AS [lag] --ETC
)
SELECT
DATEADD(day,[lag],[date]) AS [reference_date],
[otherkey1],[otherkey2],[otherkey3],
AVG([value1]) AS [avg_value1],
AVG([value2]) AS [avg_value2]
FROM [data_table]
CROSS JOIN moving_avg
GROUP BY [otherkey1],[otherkey2],[otherkey3],DATEADD(day,[lag],[date])
ORDER BY [otherkey1],[otherkey2],[otherkey3],[reference_date];