What is the best way to subtract the lowest value from all values by group?
Something like:
ID Name Value
1 A 10
1 B 40
1 C 100
2 A 20
2 B 80
2 C 90
3 A 4
3 B 7
3 C 8
turn to:
ID Name Value
1 A 0
1 B 30
1 C 90
2 A 0
2 B 60
2 C 70
3 A 0
3 B 3
3 C 4
Use window functions:
select id, name, value - min(value) over (partition by id) as
from t;
If you actually want to update the values, in MySQL, aggregation and join are probably the simplest solution:
update t join
(select id, min(value) as min_value
from t
group by id
) tt
on t.id = tt.id
set value = value - min_value
where min_value <> 0;
Related
Can someone help me do this in SQL in a select statement?
I have a table xyz as follow:
ColumnID
Column A
Column B
1
1
A
1
2
B
1
3
C
1
4
D
2
1
A
2
2
B
2
3
C
2
4
C
3
1
A
3
2
A
3
3
B
3
4
B
4
1
A
4
2
B
4
3
V
4
4
V
I want it to change to this:
Column A
Column B
1
A
2
B
3
C
4
D
1
A
2
B
3
C
1
A
2
B
1
A
2
B
3
V
haven't tried anything
Here is the solution for anyone who has the same question:
with abc as (select columnID, ROW_NUMBER() over (PARTITION by columnID, column_b ORDER BY columnID) as column_a, column_b
from xyz)
select row_number() over (partition by columnID order by column_a asc) as column_a, column_b
from abc where row_num = 1
I have this tables:
table A:
id
value
1
20
2
15
3
10
table B:
id
value
1
20
2
14
3
10
I want all the pairs where A.value >= than B.value. But for every comparison in the WHERE condition i just want the first match. In the example:
I got this query:
SELECT * FROM A, B
WHERE A.date>=B.date;
A_id
A_value
B_id
B_value
1
20
1
20
1
20
2
14
1
20
3
10
2
15
2
14
2
15
3
10
3
10
3
10
but as i said, i just want the first match of every comparison (asume that a_value and b_value are sorted)
So i want to delete (actually ignore) these values:
A_id
A_value
B_id
B_value
1
20
2
14
1
20
3
10
2
15
3
10
and obtain:
A_id
A_value
B_id
B_value
1
20
1
20
2
15
2
14
3
10
3
10
I think i can achieve the result grouping by A_id and A_value and calculating MAX(B_value) but i dont know if this is efficient.
something like this
SELECT A.id,A.Value,MAX(B_value)
FROM A, B
WHERE A.date>=B.date
GROUP BY A.id,A.value;
So the question is:
Is there a query that can give me the result i need ?
You can use ROW_NUMBER() (available in MySQL 8.x). For example:
select *
from (
select
a.id as a_id, a.value as a_value,
b.id as b_id, b.value as b_value,
row_number() over(partition by a.id order by b.value desc) as rn
from a
join b on a.id = b.id
and a.value >= b.value
) x
where rn = 1
I have a table like:
Number | Event | Weight
1 4 150
1 4 160
2 5 200
2 4 200
3 6 190
3 6 195
For each row, I would like to subtract from its Weight, the Weight of another row where Number and Event matches (if exists). The desired output is:
Number | Event | Weight | DIFF
1 4 150 -10
1 4 160 10
2 5 200 NULL
2 4 200 NULL
3 6 190 -5
3 6 195 5
Is such an operation possible? Not sure if relevant, eventually I would need to turn this query into a view. Thanks in advance.
You need a left join:
select
t.*,
t.weight - tt.weight diff
from tablename t left join tablename tt
on tt.number = t.number and tt.event = t.event and tt.weight <> t.weight
It can be done by simply substracting the column in the joined table. When one of the operands is null, the result of the arithmetic operation is null:
select a.Number, a.Event, a.Weight, a.Weight - b.Weight as DIFF
from a
left join b on a.Number = b.Number and a.Event = b.Event
I have a database scheme with a table like this:
id --- username --- sex
1 A 1
2 D 2
3 F 1
4 G 2
5 H 1
6 x 1
7 r 1
I want to select only 2 males and lets say 4 females, male is 1 and female is 2. How would we achieve that in one mysql query and if I have more var's to select by ?
(select * from your_table where sex = 1 limit 2)
union all
(select * from your_table where sex = 2 limit 4)
good evening,
i have a table:
A B C
45 1 1
22 2 1
40 3 1
43 1 2
21 2 2
61 3 2
49 4 2
60 5 2
76 1 3
41 2 3
57 3 3
i find max(A) from max(B) group by C. The result should be 60 - max number in A from last row in B from each group (C)
Thank you for your help
If i understand correctly your question you could use an inner join on select max(b):
select max(A)
from my_table m
inner join (
select C,
max(B) act_B
from my_table
group by C
) t on t.act_B = m.B and t.c = m.c