Need to select top 5 rows for each id based on desc values of a particular column , value and find the subtotal of that column . for e.g (Tried creating the situation , actual table structure is large )
ID VALUE
1 2
1 3
1 4
1 5
1 6
1 7
1 8
2 9
2 10
2 11
2 12
2 13
2 14
Output Expected
ID VALUE
1 8
1 7
1 6
1 5
1 4
TOTAL 30
2 14
2 13
2 12
2 11
2 10
TOTAL 60
I could select top 5 rows using a code like this ;
#cust_rank := IF(#current_cust = id, #cust_rank + 1, 1) AS cust_rank,
#current_cust := id
and then selecting top 5
Also ,I could subtotal using code like this ;
SELECT id, value FROM source
UNION
SELECT NULL,SUM(value) FROM source
GROUP BY id ORDER BY id;
I need to merge both requirements .
SELECT CAST(id as CHAR(50)) Id, value
FROM (SELECT id , value ,
IF(#lastid=(#lastid:=id), #auto:=#auto+1, #auto:=1) indx
FROM source, (SELECT #lastid:=0, #auto:=1) A
ORDER BY id,value desc)as A
WHERE indx <= 5
Output
Id value
1 8
1 7
1 6
1 5
1 4
2 14
2 13
2 12
2 11
2 10
2nd Query
SELECT 'Total', SUM(value)
FROM (SELECT id , value ,
IF(#lastid=(#lastid:=id), #auto:=#auto+1, #auto:=1) indx
FROM source, (SELECT #lastid:=0, #auto:=1) A
ORDER BY value desc)as A
WHERE indx <= 5
GROUP BY id ;
Output
Total SUM(value)
Total 30
Total 60
Merged Query:
Select
CASE
WHEN indx =6 THEN "Total"
ELSE id
END as ID,value
from
(
select id,value,
IF(#lastid=(#lastid:=id), #auto:=#auto+1, #auto:=1) indx
FROM
(
SELECT CAST(id as CHAR(50)) Id, value
FROM (SELECT id , value ,
IF(#lastid=(#lastid:=id), #auto:=#auto+1, #auto:=1) indx
FROM source, (SELECT #lastid:=0, #auto:=1) A
ORDER BY id,value desc)as A
WHERE indx <= 5
UNION
SELECT CAST(id as CHAR(50))as id, SUM(value)as value
FROM (SELECT id , value ,
IF(#lastid1=(#lastid1:=id), #auto1:=#auto1+1, #auto1:=1) indx
FROM source, (SELECT #lastid1:=0, #auto1:=1) A
ORDER BY value desc)as A
WHERE indx <= 5
GROUP BY id)as output ,(SELECT #lastid:=0, #auto:=1) A ORDER BY id) as output1
Output
ID value
1 8
1 7
1 6
1 5
1 4
Total 30
2 10
2 11
2 12
2 13
2 14
Total 60
Related
I'm trying to get the last completed task id of the child table while counting all the child records and completed child records:
set #tmp := 0;
select
count(*) total,
count(if(completed=1, 1, null)) completed,
#tmp:=if(completed=1, task_id, #tmp) last_completed_task_id
from child_table where parent_id = 6
order by sequence
Here is some sample data:
id parent_id completed task_id sequence
526 6 1 1 1
1653 6 0 5 2
2749 6 0 20 3
3840 6 0 21 4
4913 6 1 22 5
5983 6 0 23 6
7063 6 0 25 7
7183 6 0 26 8
8241 6 1 27 9
9317 6 0 28 10
10380 6 0 29 11
So final result should be like that:
total: 11
completed: 3
last_completed_task_id: 27
I know how to get it with separate queries, but I wish to get it with one query if possible.
You could use a cros join between the count and the max task_id eg:
select
count(*) total,
count(if(completed=1, 1, null)) completed,
t.last_completed_task_id
from child_table
cross join (
select max(task_id) last_completed_task_id
from child_table
where parent_id = 6
and completed=1 ) t
where parent_id = 6
You can easily get the last completed id using conditional aggregation:
select count(*),
sum(is_completed = 1),
max(case when is_completed = 1 then id end) as last_completed_id
from child_table ct
where parent_id = 6;
If task_id is increasing -- as in your sample data -- you can just use task_id rather than id in the max().
Otherwise, just join the table back in:
select cnt, cnt_completed, ct2.task_id
from (select count(*) as cnt,
sum(is_completed = 1) as cnt_completed,
max(case when is_completed = 1 then id end) as last_completed_id
from child_table ct
where parent_id = 6
) x join
child_table ct2
on x.last_completed_id = ct2.id
You could try this :
select count(*) total,
count(if(completed=1, 1, null)) completed,
(select task_id from child_table where parent_id = 6 and completed = 1 order by sequence desc limit 1) as last_completed_task_id
from child_table
where parent_id = 6
Table
Id name
1 Akhil
2 Akira
3 Anuj
4 Bia
5 Bina
6 Chetu
7 Chini
8 Chikna
9 Chana
Output
Id name
1 Akhil
2 Akira
3 Bia
4 Bina
6 Chetu
7 Chini
Here the Query. In the Result are more field, but you can remove them. They are only to see how the Query works
SELECT * FROM (
SELECT
#nr := IF(#old_val = SUBSTRING(t.name,1,1),(#nr +1),1) AS nr,
#old_val:=SUBSTRING(t.name,1,1) AS tmp,
t.name FROM mytable t,
(SELECT #nr:=0, #old_val:='') AS TMP
ORDER BY NAME
) AS result WHERE nr < 3;
Please let me know if it works for you
Have to show on specific count . Means i have to show max score value 4 times then less than that score to 3 times and so on
I have table like:-
ID Score
1 1
2 1
3 1
4 1
5 2
6 2
7 2
8 3
9 3
10 4
11 4
12 4
and I am expecting output like:-
Score
1
1
1
2
2
3
4
Try this:
SELECT Score
FROM
(SELECT a.Score, a.ID, count(*) as RN FROM TableName a
JOIN TableName b ON a.Score = b.Score AND a.ID >= b.ID
GROUP BY a.Score, a.ID) T
WHERE RN>1
Result:
SCORE
1
1
1
2
2
3
4
4
An example in SQL Fiddle.
Explanation:
In the inner query, we are selecting a row number partitioned by ID and order by score. And then we select Score from the inner query whose Row number is greater than 1 (inorder to omit 1 record).
SELECT x.*
FROM my_table x
JOIN my_table y
ON y.marks = x.marks
AND y.id <= x.id
GROUP
BY x.marks
, x.id
HAVING COUNT(0) <= MAX(4-x.marks)
ORDER
BY marks DESC,id;
I have data in a table like this:
fgid qty ntid
1 100 10
2 90 10
6 200 11
1 80 11
1 120 12
6 100 12
6 30 13
And i make query :
SELECT fgid, SUM(qty) AS total_qty, COUNT(ntid) AS nt_count FROM sofg
GROUP BY fgid
AND the result is :
fgid total_qty nt_count
1 300 3
2 90 1
6 330 3
Then i want to make the result like this :
no fgid total_qty nt_count
1 1 300 3
2 2 90 1
3 6 330 3
How to do that with a query? where 'no' is (like) autoincrement number.
Try this query.
SELECT
#rownum := #rownum + 1 rownum,
t.*
FROM (SELECT #rownum:=0) r,
(
SELECT fgid, SUM(qty) AS total_qty, COUNT(ntid) AS nt_count FROM sofg GROUP BY fgid
) t;
Basically the same as Dhinakaran's answer, but there's no need to put the whole main query into a subquery. There's no difference to his answer appart from maybe being more pleasing to the eye, but please accept Dhinakaran's answer, as he was faster.
SELECT
#rownum:=#rownum + 1 as rownumber,
fgid,
SUM(qty) AS total_qty,
COUNT(ntid) AS nt_count
FROM sofg
, (select #rownum:=0) v
GROUP BY fgid
I want to make a SQL query that shows me the article that generated most income. (in a shop)
Table = orderrader
rownumber articlenumber ordernumber price amount
1 11 1 8624 3
2 6 1 4794 2
3 17 1 8755 3
4 1 1 7803 1
5 16 1 8987 3
6 10 1 4575 3
7 4 1 8747 1
8 15 1 5439 3
9 11 2 8624 3
10 1 2 7803 1
Following sql statement will return only one articlenumber with max revenue.
Select articlenumber, sum(price*amount) as totalincome
from orderrader
group by articlenumber
order by sum(price*amount) desc LIMIT 1
SELECT articlenumber
FROM orderrader
WHERE (price * amount) = (SELECT MAX(price * amount) FROM orderrader)
This should do the trick, i checked it on my own database. It will give ONLY the one with the highest price*amount
SELECT articlenumber, SUM(price*amount) AS income
FROM table
GROUP BY articlenumber
ORDER BY income DESC
select articlenumber, sum(price*amount) as s from orderrader group by articlenumber order by s desc;