I have the following table:
[example]
How can I make a new table where all the duplicates are merged and the values are added together so I have a total per name ?
name value
A 34
B 25
A 18
C 14
B 16
A 9
B 4
C 9
name value
A 61
B 45
C 23
A:
SELECT name, SUM(value)
FROM tableName
GROUP BY name
use:
=QUERY(V:X; "select V,sum(W),sum(X) where V is not null group by V")
Related
After numerous joins building a query, I stuck in a table of products with 3 column identifies ID-Color-Size and the column of data barcode like
Id
Color
Size
Barcode
34
40
4
5205barcode1
34
40
4
extradata1
34
40
5
5205barcode2
34
40
5
extradata2
34
41
4
5205barcode3
34
41
4
extradata3
35
40
5
5205barcode4
35
40
5
extradata4
34
40
3
data4
35
39
5
data5
35
40
3
data6
I need to keep the unique combinations of ID-Color-Size with barcode (starting with '5205%') and remove the rows with same id-color-size (the extradata1-5 are considered duplicate).
The final table would have unique combinations of ID-Color-Size-barcode1-4 and data4-5-6
If I understand correctly you need a window function to order duplicates of id/color/size by the barcode and only select those where the barcode starts 5205:
with p as (
select *,
Row_Number() over(partition by id, color, size order by case when barcode like '5205%' then 1 end desc) rn
from t
)
select id, color, size, barcode
from p
where rn=1
ID Date Value Average
1 10/5/2017 15 15
2 10/6/2017 25 20
3 10/7/2017 35 25
4 10/8/2017 45 35
5 10/9/2017 55 45
6 10/10/2017 65 55
7 10/11/2017 75 65
If this is my table, I want average to be a computed column and its formula in general is average of previous 3 row's Value column.
(Ex. for 2nd row it is (25+15)/2 )
How can i do such a thing in computed column? Is there any better way to achieve this.
Thanks in advance.
i would go with a view and use avg windows function
select
id,
date,
value,
avg(value) over (order by id)
from table
Updated answer: you could use frames clause like below
Working Demo
;with cte(id,date,val)
as
(
select 1 ,'10/5/2017' , 15 UNION ALL
select 2 ,'10/6/2017' , 25 UNION ALL
select 3 ,'10/7/2017' , 35 UNION ALL
select 4 ,'10/8/2017' , 45 UNION ALL
select 5 ,'10/9/2017' , 55 UNION ALL
select 6 ,'10/10/2017', 65 UNION ALL
select 7 ,'10/11/2017', 75
)
SELECT *,avg(VAL) OVER (ORDER BY id rows between 2 PRECEDING and current row ) FROM CTE
I have TrsViewPay view with this sample data:
id DocTypeRef TrsDocPayItemref
---------------------------------
1 10 16
2 20 17
3 30 18
4 40 1
First I don't want to show record with DocTypeRef 40.
Then I don't want to show the records where the id is equal with that record's TrsDocPayItemref.
So I want to show this result (without record 1 and 4)
id DocTypeRef TrsDocPayItemref
---------------------------------
2 20 17
3 30 18
Ravi's answer is close, but I think this one will be better:
SELECT Id, DocTypeRef, TrsDocPayItemref
FROM TrsViewPay
WHERE DocTypeRef <> 40
AND Id <> (SELECT TrsDocPayItemref FROM TrsViewPay WHERE DocTypeRef = 40)
You can go for inner queries or sub queries. You can first Select the value of
DocTypeRef and then compare it with id. use first point as inner query. After that you can retrieve data using the result of first query.
You can try this:
SELECT *
FROM TrsViewPay
WHERE DocTypeRef!=40
AND NOT TrsDocPayItemref IN (SELECT id FROM TrsViewPay )
I have a table, which can be seen as a evaluation of two courses in several classroom tests, like this:
student_ID Evaluation Course1 Course2
------------------------------------------------------
1 5 88 93
2 4 70 87
1 5 93 90
2 5 99 91
3 3 65 60
3 4 88 70
I need to get the result of the Evaluation=5 for each student, if any. If that student has more than one Evaluation=5, the query only show any one of them. So for the above example table, the query result will be
student_ID Evaluation Course1 Course2
------------------------------------------------------
1 5 88 93
2 5 99 91
Of course in my real table, the "Courses" number is more than 2.
Thanks for the help.
Since you only want to get only one record for every student_id, you can use ROW_NUMBER() which generates sequential number. The number generated will always starts with 1 which you can use to filter out row for every partition, in this case Student_ID.
SELECT Student_ID, Evaluation, Course1, Course2
FROM
(
SELECT Student_ID, Evaluation, Course1, Course2,
ROW_NUMBER() OVER (PARTITION BY Student_ID
ORDER BY Student_ID) rn
FROM TableName
WHERE Evaluation = 5
) a
WHERE a.rn = 1
SQLFiddle Demo
In a sqlite database I have the following table:
id object val1 val2 'time stamp'
1 Z 100 102 53
2 Z 100 102 54
3 Z 100 103 55
4 A 99 123 23
5 A 23 245 35
6 A 23 245 36
7 A 23 245 37
8 A 23 245 38
9 A 99 123 119
For all kind of objects the values val1 and val2 are recorded with a time stamp.
How can I select all rows contaning a change in one of the value fields for each object.
Hence I want a select statement with the following result:
id object val1 val2 'time stamp'
1 Z 100 102 53
3 Z 100 103 55
4 A 99 123 23
5 A 23 245 35
9 A 99 123 119
Can somebody help me out with the correct sql query. Thank you.
For a record with object O and timestamp T, the following query will find the values for the relevant previous record, i.e., the record with the largest timestamp that is still smaller than T:
SELECT val1, val2
FROM MyTable
WHERE object = O
AND "time stamp" < T
ORDER BY "time stamp" DESC
LIMIT 1
By using something like this as a subquery, we can get both sets of values to compare them:
SELECT *
FROM MyTable AS T1
WHERE val1 || ',' || val2 IS NOT (SELECT T2.val1 || ',' || T2.val2
FROM MyTable AS T2
WHERE T2.object = T1.object
AND T2."time stamp" < T1."time stamp"
ORDER BY T2."time stamp" DESC
LIMIT 1)
Creating a string from both values avoids having to use two subqueries.
This uses IS NOT instead of <> because the subquery will return NULL if no previous records exists.
EDIT: Retracting this after OP has further clarified what he desires. OP wants to gather rows representing a change of object state.
This would give you the unique set of object values
select distinct object, val1, val2
Do you need an arbitrary id and a timestamp to be associated with each row for a particular purpose? That is, do you want the first occurrence? the last occurrence? of the object-value1-value2 triad?
If so you could group:
select object, val1, val2, max(timestamp) as TS from T
group by object, val1, val2
Then if you needed the id that belonged to the triad with max(timestamp) you can join the inline view back to the table on the four values.
select t.id, foo.object, foo.val1, foo.val2, foo.TS
from t
join
(
select object, val1, val2, max(timestamp) as TS from T
group by object, val1, val2
) as foo
on t.object = foo.object and t.val1 = foo.val1 and t.val2 = foo.val2
and t.timestamp = foo.TS