MySQL count multiple GroupBy - mysql

I have data like this
id otherid name
1 123 banana
2 123 banana
3 123 banana
4 456 grape
5 456 grape
6 789 orange
7 111 banana
How can I get output like this: (with MySQL query)
name count
banana 2
grape 1
orange 1

Try this:
SELECT
f.`name`,
COUNT(DISTINCT (f.`otherid`))
FROM
`fruits` f
GROUP BY f.`name`

You can use COUNT with GROUP BY:
SELECT
`name`, COUNT(*)
FROM
write_you_table_name
GROUP BY
`name`,`otherid`

Using distinct in the count function is recommended. But if you prefer not to using it, try this:
select name,count(*) from
(select name from fruit group by name,otherid) t
group by name;

SELECT name , count(*) as count FROM tb_stock GROUP BY other_id

Related

mysql group sum same table

I have the following table:
id
name
type
score
1
john
orange
2345
2
john
yellow
5
3
john
black
5454540
4
jack
orange
1123
5
jack
yellow
1000
6
jack
black
86943
7
jane
orange
9876
8
jane
yellow
10000
9
jane
black
102233
comment;
id : inte
name : same name save more times to more rows,
score: it is int data
type : it has string data black,white,yellow,purple,orange
I'm using the following queries to calculate two score totals
SELECT name,sum(score) as `first`
FROM salary
WHERE type = 'orange'
SELECT name,sum(score) as `second`
FROM salary
WHERE type in ('black','yellow')
i want see result that ( all names must be group, single name.)
name
FirstScore
SecondScore
john
2345
5454545
jack
1123
87943
jane
9876
112233
Use a conditional SUM() to aggregate the values based on type:
SELECT name
, SUM(CASE WHEN type IN ('orange') THEN score END ) AS FirstScore
, SUM(CASE WHEN type IN ('yellow','black') THEN score END ) AS SecondScore
FROM salary
GROUP BY Name
Results:
name
FirstScore
SecondScore
john
2345
5454545
jack
1123
87943
jane
9876
112233
db<>fiddle here
Something like this (but this is untested):
SELECT
salary.name,
first.score as "first_score",
second.score as "second_score"
FROM salary
LEFT JOIN (SELECT name,sum(score) as score
FROM salary
WHERE type = 'orange'
) as first ON first.name = salary.name
LEFT JOIN (SELECT name,sum(score) as score
FROM salary
WHERE type in ('black','yellow')
) as second ON second.name = salary.name

Select rows where ID is same but Name contains different data in more than one record

ID Name
---------
1 ABC
1 123
2 BCD
3 CDE
4 AAA
4 ZZZ
Desired Result
ID Name1 Name2
---------------------
1 ABC 123
2 BCD NULL
3 CDE NULL
4 AAA ZZZ
You could just use aggregation:
select id, min(name) name1, case when min(name) <> max(name) then max(name) name2
from mytable
group by id
You can use aggregation:
select id, min(name) as name1,
nullif(max(name), min(name)) as name2
from t
group by id;
If you just want a list of all names, then use a single column for the names and use group_concat():
select id, group_concat(name) as names
from t
group by id;

SQL get perticuler name arranged in the middle of query

I have a column fruits and it has rows like
banana
pineapple
orange
grapes
apple
mango
pomegranate
Kiwi
grapefruit
peach
or maybe like this
pineapple
grapefruit
orange
grapes
apple
mango
pomegranate
Kiwi
banana
peach
I want to retrieve all that with grapefruit in the middle all the time like following no matter whether it has even or odd number of rows
banana
pineapple
orange
grapes
grapefruit
apple
pomegranate
Kiwi
mango
I know basic SQL query SELECT fruit FROM FRUITTABLE
but dont know further
You can order by is_even/is_odd on some enumeration. (here: the difference in row_number() over nothing)
\i tmp.sql
CREATE TABLE fruits(fruit text);
INSERT INTO fruits(fruit) VALUES
('banana') ,('pineapple') ,('orange') ,('grapes') ,('apple') ,('mango') ,('pomegranate') ,('Kiwi') ,('grapefruit') ,('peach')
;
with numbered AS (
select fruit, row_number() OVER () rn
FROM fruits
)
, gnum AS (
SELECT rn FROM numbered
WHERE fruit = 'grapefruit'
)
SELECT n.fruit, n.rn
FROM numbered n
JOIN gnum g ON true
ORDER BY ((n.rn - g.rn) %2), (n.rn <> g.rn)
;
Result:
CREATE TABLE
INSERT 0 10
fruit | rn
-------------+----
mango | 6
grapes | 4
Kiwi | 8
pineapple | 2
grapefruit | 9
banana | 1
orange | 3
apple | 5
pomegranate | 7
peach | 10
(10 rows)
Edit: the tie-breaker is not always correct (caused by modulo on negative numbers) A better order would be
ORDER BY (ABS(n.rn - g.rn) %2) , (n.rn <> g.rn) DESC
I think you should explain why you want to do this, maybe there is a better way to do obtain the result you want.
But I think that you could add a weight col in your table
and order by that value in the select.
Just take into consideration that whenever you add a new row you have to update that weights in order to maintain grapefruit in the middle.
And you have to define how to manage the pair numbers of rows.
Table with examples
SELECT *
FROM Fruits
ORDER BY Weight;
Could you do:
(select * from fruit where id < (select max(id)/2 from fruit))
union select * from fruit where id = grapefruit
union
(select * from fruit where id > (select max(id)/2 from fruit))
Or something like that. If you don't have an id you might have to use rownumber, but it should be doable.

Count appearances of a value in any column of a table

How can I count up the total appearances of a value in multiple columns?
Raw Table:
col1 col2
---- ----
don sam
jon sam
mike lisa
sam lisa
lisa beth
Result:
name appearances
---- -----------
don 1
sam 3
jon 1
mike 1
lisa 3
beth 1
I've tried writing a join where getting the total count is a subquery, but this seems awkward. I'm assuming MySQL has some way to handle this nicely.
Here's one way using UNION ALL:
select name, count(1) cnt
from (
select col1 as name from yourtable
union all
select col2 from yourtable
) t
group by name
SQL Fiddle Demo
Results:
NAME CNT
-----------
beth 1
don 1
jon 1
lisa 3
mike 1
sam 3
try this
select name , count(*) as appearances from
(
select col1 as name from Raw
union all
select col2 as name from Raw
)t
group by name
DEMO HERE

how to condense consecutive duplicate rows in Mysql?

In a mysql database, how can I condense all consecutive duplicates into 1 while maintaining order in a select output?
data:
id fruit
----------
1 Apple
2 Banana
3 Banana
4 Banana
5 Apple
6 Mango
7 Mango
8 Apple
Output I want:
fruit
-------
Apple
Banana
Apple
Mango
Apple
This is a very easy thing to do in unix with the uniq command, but 'distinct' is not as flexible.
IDs are not sequential, and gaps are possible. I was oversimplifying in my example.
Select could be like this:
data:
id fruit
----------
100 Apple
2 Banana
30 Banana
11 Banana
50 Apple
62 Mango
7 Mango
4 Apple
Try this - assuming consecutive IDs with no gaps.
SELECT T.fruit
FROM YOURTABLE T
LEFT JOIN YOURTABLE T2
ON T2.ID = T.ID + 1
WHERE T2.fruit <> T.fruit
OR T2.ID IS NULL
ORDER BY T.ID
Use:
SELECT x.fruit
FROM (SELECT t.fruit,
CASE
WHEN #fruit <> t.fruit THEN #rownum := #rownum + 1
ELSE #rownum
END as rank
FROM YOUR_TABLE t
JOIN (SELECT #rownum := 0, #fruit := NULL) r
ORDER BY t.id) x
GROUP BY x.fruit, x.rank
ORDER BY x.rank