I am looking to pivot the rows in the attached image and I want the output to look something like this
ID Age Factor
1 30 8.650
1 35 11.52
1 40 13.87
till 100
2 30 7.99
2 35 10.98
2 40 13.43
till 100
3 30 7.32
3 35 10.98
3 40 13.43
till 100
and so on until i reach the last row (81) in the attached data source.
Thank you :)
Source data
Finally got it working -
SELECT a.ID - 1 AS ID, b.Age, CAST(b.Factor AS DECIMAL(19,2)) AS Factor
from t1 a -- data source table.
cross apply (values
(30, F1),
(35, F2),
(40, F3),
(45, F4),
(50, F5),
(55, F6),
(60, F7),
(65, F8),
(70, F9),
(100, F10)
) b(Age, Factor)
where a.ID >= 2
Related
I would like to identify the last state for a variable regarding a specific month. For example
Variable Date Operation State
A 01Jan2019 1 10
A 10Jan2019 3 20
A 31Jan2019 4 50
A 05Feb2019 7 60
A 22Feb2019 8 70
B 06Jan2019 2 10
B 07Jan2019 3 20
B 07Feb2019 6 60
B 15Mar2019 9 80
The result should like
Variable Month Year Last_State_Until_End_of_Month
A 1 2019 50
A 2 2019 70
A 3 2019 70
B 1 2019 20
B 2 2019 60
B 3 2019 80
Please note that for the variable A in March the last state is the same as for February. (No change was made during March). I don't know if it helps, but there is an operation ID the is increasing for each change of a state independent of the choise of variable.
Thanks Panagiotis Kanavos the follwoing query works:
declare #table_test TABLE (variable_name nvarchar(255), date_var date, op_id int, state int)
insert into #table_test Values
('A', '01Jan2019', 1 ,10),
('A', '10Jan2019', 3 ,20),
('A', '31Jan2019', 4 ,50),
('A', '05Feb2019', 7 ,60),
('A', '22Feb2019', 8 ,70),
('B', '06Jan2019', 2 ,10),
('B', '07Jan2019', 3 ,20),
('B', '07Feb2019', 6 ,60),
('B', '15Mar2019', 9 ,80)
select
year(date_var) as year
,month(date_var) as month
,variable_name,
,Last_value(State) OVER (partition by year(date_var),month(date_var),variable_name order by date_var ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) as last_value
from #table_test
Order by variable_name, year(date_var),month(date_var)
This query returns:
year month variable_name last_value
2019 1 A 50
2019 1 A 50
2019 1 A 50
2019 2 A 70
2019 2 A 70
2019 1 B 20
2019 1 B 20
2019 2 B 60
2019 3 B 80
I'm attempting to find rows given a list of values where one of the values is in a range between two of the columns, as an example:
id column1 column2
1 1 5
2 6 10
3 11 15
4 16 20
5 21 25
...
99 491 495
100 496 500
I'd like to give a list of values, e.g. (23, 83, 432, 334, 344) which would return the rows
id column1 column2
5 21 25
17 81 85
87 431 435
67 331 335
69 341 345
The only way I can think of doing this so far has been to split each into it's own call by doing
SELECT * FROM TableA WHERE (column1 < num1 AND num1 < column2)
However this scales quite poorly when the list of numbers is around several million.
Is there any better way of doing this?
Thanks for the help.
Putting millions of numbers into the SQL command itself would be unwieldy.
Obviously, you have to put the numbers into a (temporary) table.
Then you can just join the two tables:
SELECT *
FROM TableA JOIN TempTable
ON TempTable.Value BETWEEN TableA.column1 AND TableA.column2;
I have a requirement where in there are forecasted values of few offices which are linked to one main office.
For example,office 1,office 2, office 3 are linked to mainoffice.Forecasted values are for entire month.Now I need to use some formula to create demand for mainoffice based on its link offices.
1 2 3 4 5 28 29 30
office1 100 200 300 150 120 100 130 160
office2 200 100 150 200 130 160 120 100
office3 400 350 200 400 260 100 130 200
now main office in the month
required output - ((officetotal1+officetotal2+officetotal3)/30)*5
This same value has to be put in the form of 3 buckets for month
i.e 1st 11th and 21st
1 11 21
mainoffice1 X X X
mainoffice2 Y Y Y
Mapping
office mainoffice
------ ---------
office1 mainoffice1/n
office2 mainoffice1/n
office3 mainoffice2/n
You do this with a join. It is something like:
proc sql;
select o.mainoffice, sum(val1) as val1, sum(val2) as val2, . . .
from forecasts f join
offices o
on f.office = o.office
group by o.mainoffice;
The point is to do a join to get the main office information and then to do an aggregation for the values you want.
EDIT:
Then you just add together the values that you want:
select o.mainoffice,
sum(val1 + val2 + . . . val10 + val11) as val1_11,
. . .
from forecasts f join
offices o
on f.office = o.office
group by o.mainoffice;
I have the below input
PlayerID MatchPlayed RunsMade
-------- ----------- --------
1 10 200
2 5 100
3 8 24
4 30 50
The output will be
Combined Players Combined Match Played Combined runs Made
---------------- --------------------- ------------------
1 10 200
1,2 15 300
1,3 18 224
1,4 40 250
1,2,3 23 324
1,2,4 45 350
1,3,4 48 274
1,2,3,4 53 374
2 5 100
2,3 13 124
2,4 35 150
2,3,4 43 174
3 8 24
3,4 38 74
4 30 50
The Combined Match Played column is the sum of the values of Match Played column of those players. e.g. for Combined Played 1,2 the Combined Match Played value is 10 + 5 = 15.
similarly, Combined Runs Made is the sum of the Runs MAde column of the individual players. e.g. for the same example, the Combined Runs MAde column is 200 +100 =300.
Thanks
Setup:
create table Input(PlayerId int, MatchPlayed int, RunsMade int)
insert Input
select 1, 10, 200
union all select 2, 5, 100
union all select 3, 8, 24
union all select 4, 30, 50
Query:
with cte(Combined, PlayerId, MatchPlayed, RunsMade)
as
(
select cast(PlayerId as varchar(500)), PlayerId, MatchPlayed, RunsMade
from Input
union all
select cast(cte.Combined + ',' + cast(inp.PlayerId as varchar) as varchar(500)), inp.PlayerId, inp.MatchPlayed + cte.MatchPlayed, inp.RunsMade + cte.RunsMade
from cte
join Input inp on
cte.PlayerId < inp.PlayerId
)
select Combined, MatchPlayed, RunsMade
from cte
order by Combined
I'm pretty new to SQL.
I have a database with records based on road/milepoints. My goal is to get an average value every 52.8 ft along the road. My related table has data every 15 ft, this table of course has a foreign key relating it to the primary table.
If I wanted to pull out the average value every 52.8 ft, along a given milepost, how would I go about this?
Example Data:
RecID Begin_MP End_MP
100 0 0.56
RecID MP Value1 Value2
100 0 159 127.7
100 0.003 95.3 115.3
100 0.006 82.3 107
100 0.009 56.5 74.5
100 0.011 58.1 89.1
100 0.014 95.2 78.8
100 0.017 108.9 242.5
100 0.02 71.8 73.3
100 0.023 84.1 80.2
100 0.026 65.5 66.1
100 0.028 122 135.8
100 0.031 99.9 230.7
100 0.034 95.7 111.5
100 0.037 127.3 74.3
100 0.04 140.7 543.1
The first Data is an example of a Road. The second subset of data are the values I need to query out every 52.8 ft.
Thank you
You could group the data in 52.8 feet blocks. One way to do that is to divide the distance by 52.8, and round that to a whole number. That way, 25 belongs to group 1, 100 belongs to group 2, 110 belongs to group 3, and so on.
In SQL Server, you'd write this like:
select
52.8 * cast(dist/52.8 as int) as Distance
, avg(value1)
, avg(value2)
from YourTable
group by cast(dist/52.8 as int)
Below is an example with your data. Because the data runs from 0 to 0.04, I've made it calculate averages per 0.01 feet block:
declare #Road table (RecID int, Begin_MP float, End_MP float)
insert into #Road select 100, 0, 0.56
declare #Values table (RecID int, MP float, Value1 float, Value2 float)
insert into #Values values
(100, 0 , 159 , 127.7),
(100, 0.003, 95.3 , 115.3),
(100, 0.006, 82.3 , 107),
(100, 0.009, 56.5 , 74.5),
(100, 0.011, 58.1 , 89.1),
(100, 0.014, 95.2 , 78.8),
(100, 0.017, 108.9, 242.5),
(100, 0.02 , 71.8 , 73.3),
(100, 0.023, 84.1 , 80.2),
(100, 0.026, 65.5 , 66.1),
(100, 0.028, 122 , 135.8),
(100, 0.031, 99.9 , 230.7),
(100, 0.034, 95.7 , 111.5),
(100, 0.037, 127.3, 74.3),
(100, 0.04 , 140.7, 543.1);
select
r.RecID
, cast(v.MP/0.01 as int)*0.01 as StartMP
, AVG(v.Value1) as AvgVal1
, AVG(v.Value2) as AvgVal2
from #Road as r
left join #Values as v
on r.RecID = v.RecID
group by r.RecID, cast(v.MP/0.01 as int)
This prints:
RecID StartMP AvgVal1 AvgVal2
100 0.00 98,275 106,125
100 0.01 87,4 136,8
100 0.02 85,85 88,85
100 0.03 107,63 138,83
100 0.04 140,7 543,1