I have two tables that will be a and b. I want to compare number in a to number in b where they share an ID. a has a single row, while b has multiple. If the sum of b is less than a, then that row of a should be added to the total sum, otherwise it should be skipped.
Table a
ID Number
4 50
5 60
6 70
Table b
ID Number SharedID
1 30 4
2 25 4
3 50 5
4 5 5
5 30 6
6 10 6
Using that example: b 1 and 2 are greater than a 4, so it wouldn't be counted. b 3 and 4 are less than a 5 so it would count. b 5 and 6 are less than a 6, so it would count. The total should be 130.
I'm having trouble with doing a comparison of one row to multiple and then only summing some of the numbers.
This should do the job:
select sum(Number)
from a
where Number > (select sum(Number) from b where b.SharedID = a.ID)
Try this query:
SELECT SUM(a.Number)
FROM a INNER JOIN
(
SELECT b.SharedID, SUM(b.Number) AS theSum
FROM b
GROUP BY b.SharedID
) t
ON a.ID = t.SharedID
WHERE t.theSum < a.Number
The conceptually easiest option is to create a temporary table containing the sums of Table b, and then to JOIN that back to Table a. The WHERE clause restricts your total to only a Number values which are greater than the b sum.
select SUM(number) from(
select case when(aa.number>(select SUM(bb.number)
from bb where bb.sharedid=aa.id))then aa.number else 0 end as number from aa )abc
This should do the trick
Related
We have a table of our sold items, it looks like this : ( Table A )
id
sell_id
item
amount
11
5
A
3000
12
5
B
2000
13
6
A
5120
14
7
C
5000
and a table where shipped items are placed that looks like this : ( Table B )
id
sub_id
item
amount
1
11
A
2850
2
11
A
150
3
12
B
2100
( Table B is matched to Table A by referencing TableA.id in Table B as sub_id ).
I want to find rows that sum of amount per TableA.id is not equivalent of sum of TableB.amount per TableB.sub_id.
In other words I want to know which sold items are not shipped exactly as the amount which is sold.
I've tried left joining tableA to tableB but i cannot get it to work.
Any help would be appreciated. Thanks!
For example:
SELECT a.*
FROM a
WHERE NOT EXISTS ( SELECT NULL
FROM b
WHERE a.id = b.sub_id
GROUP BY b.sub_id
HAVING a.amount = SUM(b.amount) )
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1b13c67b6e622a5da72f63074d53d423
I have a table with the columns : id, status, value.
id status value
-- ------ -----
1 10 100
2 10 100
3 10 60
4 11 20
5 11 15
6 12 100
7 12 50
8 12 50
I would like to get the id and value of the first and second highest valued rows, from each status group. My table should have the following columns:
status, id of the first highest value, first highest value, id of second highest value, second highest value.
I should get:
status 1stID 1stValue 2ndID 2ndValue
------ ----- -------- ----- --------
10 1/2 100 2/1 100
11 4 20 5 15
12 6 100 7/8 50
I tried all kinds of solutions, but I couldn't find a solution for same-value 1st s (two rows with the same value, which happened to be the highest in that status group) or same-value seconds.
For example, in case of two rows sharing the highest value in their status group, this not-so-elegant query will return two rows with the same status, different 1sts and same 2nd:
SELECT 2nds.status, 1sts.id AS "1stID",1sts.value AS "1stValue",
2nds.id AS "2ndID",2nds.value AS "2ndValue"
FROM
(SELECT v.* FROM
(SELECT status, MAX(value) AS "SecMaxValue" FROM table o
WHERE value < (SELECT MAX(value) FROM table
WHERE status = o.status
GROUP BY status) AS m
INNER JOIN table v
ON v.status = m.status AND v.value = m.SecMaxValue) AS 2nds
INNER JOIN
(SELECT v.* FROM
(SELECT status, MAX(value) AS maxValue FROM table
GROUP BY status) AS m
INNER JOIN table v
ON v.status = m.status AND v.value = m.MaxValue) AS 1sts
ON 1sts.status = 2nds.status ;
This query will give me:
status 1stID 1stValue 2ndID 2ndValue
------ ----- -------- ----- --------
10 1 100 3 60
10 2 100 3 60
11 4 20 5 15
12 6 100 7 50
12 6 100 8 50
To conclude, I would like to find a solution in which:
a. if there are two rows with the highest value the query puts the details one of them in the column of the 1st and the details of other in 2nd (no mather which)
b. if there are two rows with the second highst value it puts the highest in its place and one of the seconds in the second place.
Is there a way to change the query above? someone has a nicer solution?
I came across several 1st and 2nd queries but they had the same problem - for example this solution: Finding the highest n values of each group in MySQL. it does not deliver 1st and 2nd in the same row, but the main problem it provides only one of the firsts.
Thanks
After spent a lot of time, finally I found a solution for above problem. Please try it out:
select 1st.status as Status,
SUBSTRING_INDEX(1st.id,'/',1) as 1stID,
1st.value as 1stValue,
(case when locate('/',1st.id) > 0 then SUBSTRING_INDEX(1st.id,'/',-1)
else 2nd.id
end) as 2ndID,
(case when locate('/',1st.id) > 0 then 1st.value
else 2nd.value
end) as 2ndValue
from
(
(select status, SUBSTRING_INDEX(Group_concat(id separator '/'),'/',2) as id,value
from t1
where (status,value) in (select status,value
from t1
group by status
having max(value))
group by status) 1st
inner join
(select status,id,value
from t1
where (status,value) not in (select status,value
from t1
group by status
having max(value))
group by status,value
order by status,value desc) 2nd
on 1st.status = 2nd.status)
group by 1st.status;
Just replace t1 with your tablename and it should work like a charm.
Click here for Updated Demo
If you have any doubt(s), feel free to ask.
Hope it helps!
My question is pretty similar to this one Auto number and reset count for each different column value
except that I can't make it work.
I have the table record:
ID(autoINC) plate_number
1 A
2 A
3 A
4 B
5 B
6 C
7 C
I want to display something like this adding additional field cc:
I have the table record:
ID(autoINC) plate_number count
1 A 1
2 A 2
3 A 3
4 B 1
5 B 2
6 C 1
7 C 2
You can have a correlated subquery which sequentially count the row which can be used as a rownumber.
SELECT A.ID,
A.plate_number,
(
SELECT COUNT(*)
FROM tableName c
WHERE c.plate_number = a.plate_number AND
c.ID <= a.ID) AS RowNumber
FROM TableName a
SQLFiddle Demo
I have a table of data like this:
id user_id A B C
=====================
1 15 1 2 3
2 15 1 2 5
3 20 1 3 9
4 20 1 3 7
I need to remove duplicate user ids and keep the record that sorts lowest when sorting by A then B then C. So using the above table, I set up a temp query (qry_temp) that simply does the sort--first on user_id, then on A, then on B, then on C. It returns the following:
id user_id A B C
====================
1 15 1 2 3
2 15 1 2 5
4 20 1 3 7
3 20 1 3 9
Then I wrote a Totals Query based on qry_temp that just had user_id (Group By) and then id (First), and I assumed this would return the following:
user_id id
===========
15 1
20 4
But it doesn't seem to do that--instead it appears to be just returning the lowest id in a group of duplicate user ids (so I get 1 and 3 instead of 1 and 4). Shouldn't the Totals query use the order of the query it's based upon? Is there a property setting in the query that might impact this or another way to get what I need? If it helps, here is the SQL:
SELECT qry_temp.user_id, First(qry_temp.ID) AS FirstOfID
FROM qry_temp
GROUP BY qry_temp.user_id;
You need a different type of query, for example:
SELECT tmp.id,
tmp.user_id,
tmp.a,
tmp.b,
tmp.c
FROM tmp
WHERE (( ( tmp.id ) IN (SELECT TOP 1 id
FROM tmp t
WHERE t.user_id = tmp.user_id
ORDER BY t.a,
t.b,
t.c,
t.id) ));
Where tmp is the name of your table. First, Last, Min and Max are not dependent on a sort order. In relational databases, sort orders are quite ephemeral.
I have a table containing jobs to be invoiced. Each row contains two columns, 'value' and 'group'. Like this
ID Value Group
1 2000.00 1
2 2000.00 1
3 1000.00 0
4 1000.00 0
What I need to do is combine the values in Rows 1 and 2 (because they have the same group number), then return rows 3 and 4 as normal (so, not grouped together):
4000 //Rows 1 and 2 combined
1000 //Row 3 returned as whole value
1000 //Row 4 returned as whole value
I've tried to use GROUP BY in the query, so something like
SELECT SUM(Value) AS totalValue FROM table GROUP BY Group
However this returns
4000
2000 //Row 3 and 4 combined
It's combining Row 3 and 4 because they share the same Group number, its grouping them together.
My problem is, I don't want them grouped together. I want them to return separately as they have a value of zero. Is there any way for me to do this?
SELECT Group AS Unique_ID, SUM(Value) AS totalValue FROM table WHERE Group>0 GROUP BY Group
UNION
SELECT id AS Unique_ID, Value As totalValue FROM table WHERE Group=0