sql query adding previous value to next value [duplicate] - sql

This question already has answers here:
Cumulative Total in MS Sql server [duplicate]
(6 answers)
Closed 8 years ago.
I want to add two columns values of my table E.g:
Id Distance Duration ETA_Distance ETA_Duration
1 0 0 20 60
2 14 20 NULL NULL
3 12 10 NULL NULL
4 15 70 NULL NULL
Considering the table above, I want a SQL query which give me the result like below:
Id Distance Duration ETA_Distance ETA_Duration
1 0 0 20 60
2 14 20 34 80
3 12 10 46 90
4 15 70 61 160

Mohan, see the below answer, It should help you.
Replace the #table with your table.
I used the temp table just to test the code.
Declare #tab table (Id int,Distance int, Duration int, ETA_Distance int, ETA_Duration int)
Insert into #tab values
(1,0 , 0,20 ,60 ),
(2,14, 20,NULL,NULL),
(3,12, 10,NULL,NULL),
(4,15, 70,NULL,NULL)
Select X.Id,X.Distance,X.Duration,
Y.ETA_Distance,Y.ETA_Duration
From #tab X
Join (
Select B.Id,
Sum(A.Distance) ETA_Distance,
Sum(A.Duration) ETA_Duration
From (Select Id,ISNULL(ETA_Distance,Distance) Distance,ISNULL(ETA_Duration,Duration) Duration From #tab) A,
(Select Id,ISNULL(ETA_Distance,Distance) Distance,ISNULL(ETA_Duration,Duration) Duration From #tab) B
Where A.Id <= B.Id
Group By B.Id) Y
On X.Id = Y. Id
Result:
Sql may look lengthy, but the logic is simple.

Related

Problems sorting data from SQL Server

My problem is, to order these results in such a way that the order is as it is marked gray.
That is to say to obtain every first difference of the column EjeY.
Might be you are looking for this:
DECLARE #Dummy TABLE(ID INT IDENTITY, EjeY VARCHAR(100),Valor INT);
INSERT INTO #Dummy VALUES
('Alta/Deviciente',14)
,('Baja/Baja',16)
,('Baja/Media',14)
,('Alta/Alta',8)
,('Alta/Baja',12)
,('Baja/Deviciente',18)
,('Baja/Alta',12)
,('Alta/Optima',6)
,('Alta/Media',10)
,('Baja/Optima',10);
SELECT *
FROM #Dummy AS d
ORDER BY LEFT(EjeY,CHARINDEX('/',EjeY)-1),Valor DESC
The result
ID EjeY Valor
1 Alta/Deviciente 14
5 Alta/Baja 12
9 Alta/Media 10
4 Alta/Alta 8
8 Alta/Optima 6
6 Baja/Deviciente 18
2 Baja/Baja 16
3 Baja/Media 14
7 Baja/Alta 12
10 Baja/Optima 10
If you only want to record the changes in the left part of your Ejey delimited field then you need to split the field and then order rank the values by ID.
After you have a ranking you can select the records you are interested in taking the first row of the PARTITION.
DECLARE #Dummy TABLE(ID INT, EjeY VARCHAR(100),Valor INT);
INSERT INTO #Dummy VALUES
(1,'Alta/Deviciente',14)
,(2,'Alta/Baja',12)
,(6,'Baja/Optima',10)
,(7,'Baja/Alta',12)
,(11,'Deficiente/Deficiente',20)
,(11,'Deficiente/Baja',18)
,(16,'Media/Alta',10)
,(17,'Media/Optima',8)
--This query will draw a rank in your data based on the LEFT() partition of your Ejey field value.
SELECT
*,
RowNumber=ROW_NUMBER() OVER(PARTITION BY SortPart ORDER BY ID DESC)
FROM
(
SELECT
ID,
SortPart=LEFT(EjeY,CHARINDEX('/',EjeY)-1),
Valor
FROM
#Dummy
)AS X
--This query will further order only the records within your ideal set of data
SELECT
*
FROM
(
SELECT
*,
RowNumber=ROW_NUMBER() OVER(PARTITION BY SortPart ORDER BY ID ASC)
FROM
(
SELECT
ID,
SortPart=LEFT(EjeY,CHARINDEX('/',EjeY)-1),
Valor
FROM
#Dummy
)AS X
)AS Y
WHERE
RowNumber=1
--Results A
ID SortPart Valor RowNumber
2 Alta 12 1
1 Alta 14 2
7 Baja 12 1
6 Baja 10 2
11 Deficiente 20 1
11 Deficiente 18 2
17 Media 8 1
16 Media 10 2
--Results B
ID SortPart Valor RowNumber
1 Alta 14 1
6 Baja 10 1
11 Deficiente 20 1

How to add two values of the same column in a table

Consider the following table?
ID COL VALUE
1 A 10
2 B 10
3 C 10
4 D 10
5 E 10
Output:
ID COL VALUE
1 A 10
2 B 20
3 C 30
4 D 40
5 E 50
Based on your (deleted) comment in output it is taking up the sum of the upper values, it sounds like you're wanting a cumulative SUM().
You can do this with a windowed function:
Select Id, Col, Sum(Value) Over (Order By Id) As Value
From YourTable
Output
Id Col Value
1 A 10
2 B 20
3 C 30
4 D 40
5 E 50
Please make use of the the below code to obtain the cumulative sum. The code is working as expected with SQL Server 2012.
DECLARE #Table TABLE (ID int, COL CHAR(2), VALUE int)
INSERT #Table
(ID,COL,[VALUE])
VALUES
(1,'A',10),
(2,'B',10),
(3,'C',10),
(4,'D',10),
(5,'E',10)
SELECT t.ID,t.COL,SUM(VALUE) OVER (ORDER BY t.ID) AS VALUE
FROM #Table t
Not really sure what you are asking for. If my assumption is correct, you want to SUM the contents of a column and group it.
Select sum(value), col
from table
group by col

Assigning a value of data for each record having the same condition in SQL Server 2008

I have a table in SQL Server 2008 like:
Period Name Value
1 A 10
2 A 20
3 A 30
4 A 40
1 B 50
2 B 80
3 B 70
4 B 60
What I need to write a select query includes a new column MainValue which contains the value where period=4 for a name for each data.
Example:
Period Name Value MainValue
1 A 10 40
2 A 20 40
3 A 30 40
4 A 40 40
1 B 50 60
2 B 80 60
3 B 70 60
4 B 60 60
How can I provide this? I tried the one below, but it is not working as I want.
Select
*,
(select Value where Period = 4) as MainValue
from myTable;
Any help would be appreciated.
Try this:
SELECT Period, Name, Value,
MAX(CASE WHEN Period=4 THEN Value END) OVER (PARTITION BY Name) AS MainValue
FROM mytable
The query uses a window function with a condition applied over Name partitions: the function returns the Value corresponding to Period=4 inside each partition.
You can do this a number of ways. A correlated sub-query as the column, a cross apply to a correlated query, or a cte. I personally like the cte approach. It would look something like this.
with MainValues as
(
select Name
, Value
from SomeTable
where Period = 4
)
select st.*
, mv.Value as MainValue
from SomeTable st
join MainValues mv on st.Name = mv.Name

Select Previous Record in SQL Server 2008

Here's the case: I have one table myTable which contains 3 columns:
ID int, identity
Group varchar(2), not null
value decimal(18,0), not null
Table looks like this:
ID GROUP VALUE Prev_Value Result
------------------------------------------
1 A 20 0 20
2 A 30 20 10
3 A 35 30 5
4 B 100 0 100
5 B 150 100 50
6 B 300 200 100
7 C 40 0 40
8 C 60 40 20
9 A 50 35 15
10 A 70 50 20
Prev_Value and Result columns should be custom columns. I need to make it on view. Anyone can help? please... Thank you so much.
The gist of what you need to do here is to join the table to itself, where part of the join condition is that the value column of the joined copy of the table is less than value column of the original. Then you can group by the columns from the original table and select the max value from the joined table to get your results:
SELECT t1.id, t1.[Group], t1.Value
, coalesce(MAX(t2.Value),0) As Prev_Value
, t1.Value - coalesce(MAX(t2.Value),0) As Result
FROM MyTable t1
LEFT JOIN MyTable t2 ON t2.[Group] = t1.[Group] and t2.Value < t1.Value
GROUP BY t1.id, t1.[Group], t1.Value
Once you can update to Sql Server 2012 you'll also be able to take advantage of the new LAG keyword.

How to find distance between two columns in different tables in geom datatype

Update the value in the column "distance" of table 1 by finding the distance between center_geom from table2 and home_location from table 3.
Table 1
obu_id end_location trip_id end_loc_adj distance
1 51 1234
2 57 1357 44
2 63 1351
3 21 1212 20
3 23 4313
Table 2
id obu_id center_geom
int int geom
51 2 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
52 3 "0101000020ED080000AE47E17A35F73341FE65F764723C0841"
57 3 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
21 4 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
Now, see table 1: If we have any value in end_loc_adj then the column : end_loc_adj has to be used rather end_loc Hint: use if-else.
Column name "end_loc" in table 1 has same values as column "id" in table 2.
Table 3
hhid obu_id home_location
(character Int geometry
varying)
11 1 "0101000020ED08000082E2C7A0B2413341BC5818A21F000941"
15 2 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
17 3 "0101000020ED0800006DFFCAA2A2553341B20E4717774E0C41"
17 4 "0101000020ED080000B81E852BC555334186048C9EB1C21141"
22 7 "0101000020ED080000AE47E17A35F73341FE65F764723C0841"
I have tried the following:
select ST_Distance_Sphere ( ST_AsText(cast(v.house_location AS text)) , ST_AsText(cast(l.center AS text)))
from public.locations l, clean.vehicles v
where l.obu_id=v.obu_id
and l.obu_id=3
but this works manually for single obu_id
I want to complete it in one go using a function.
Please give me some idea about how to do this.
Thanks.
house_loc:=(select house_location from table1 where obu_id=b.obu_id);
house_loc_geom := ST_Transform(house_loc,4269);
IF b.end_location_adj IS null THEN
end_loc:= (select center from table2 where id=b.end_location and obu_id= b.obu_id);
else
end_loc:= (select center from tabl2 where id = b.end_location_adj and obu_id = b.obu_id);
end if;
center_geom:=ST_Transform(end_loc,4269);
UPDATE table 1 set dist_from_home_in_meter=distance
where obu_id=b.obu_id and trip_id=b.trip_id and end_location=b.end_location;
this is close to answer, need some modifications.