Let me explain with example,
id firstname lastname Mark
--------------------------------
1 arun prasanth 40
2 ann antony 45
3 sruthy abc 41
6 new abc 47
1 arun prasanth 45
1 arun prasanth 49
2 ann antony 49
and AS IS, if I query like:
select count(*) as count, firstname, lastname, Mark
from tableA
group by id
order by count desc
then in the result, 3 arun ~~ row will be on the top. I have to keep this order(count desc)
But I want to search each Mark score which are 49 45 40.
I want to put result in $sql and use it like $sql['(every mark score for ann)'], how do I do that?
Use GROUP_CONCAT:
SELECT COUNT(*) AS COUNT, firstname, lastname, GROUP_CONCAT(mark) AS Mark
FROM tableA
GROUP BY id
ORDER BY COUNT DESC
This will show mark like '40, 45, 49' with comma. If you don't want comma, add SEPARATOR in the GROUP_CONCAT like below:
SELECT COUNT(*) AS COUNT, firstname, lastname, GROUP_CONCAT(mark SEPARATOR ' ') AS Mark
FROM tableA
GROUP BY id
ORDER BY COUNT DESC
This will use a space(' ') as separator instead of comma like '40 45 49'. Of course you can define any separator you want.
Use Having clause on your query for result
select count(*) as count, firstname, lastname, Mark
from tableA
group by id having by firstname = 'ann'
order by count desc
If you want the original data, use count() or a subquery in the order by:
select a.*
from tableA a
order by count(*) over (partition by id) desc,
id
In older versions of MySQL, you can use a subquery instead:
select a.*
from tableA a
order by (select count(*) from tableA a2 where a2.id = a.id) desc,
id
Related
I have been looking for a way to do a MySQL select to get all the most occuring values. All the solutions i have found where with using LIMIT 1, but this doesn't help if there are more than one value that occur the same amount of times. E.g:
customer
ID
FirstName
1
Bob
2
Tom
3
Bob
4
Robert
5
Tom
6
Timothy
The Select for most occuring FirstNames should result in:
FirstName
Bob
Tom
Since both occur twice.
I have tried the following:
SELECT FirstName FROM (
SELECT FirstName, COUNT(FirstName) as counter FROM customer
GROUP BY FirstName
HAVING counter = MAX(counter)
) s
But this doesn't seem to work, i would really appreciate a nudge in the right direction.
There can be different ways for doing this
you can try
1st
SELECT FIRSTNAME
FROM customer
GROUP BY FirstName Having count(FirstName) = (
SELECT COUNT(FirstName) FROM customer GROUP BY FirstName ORDER BY 1
DESC LIMIT 1);
2nd
with cte as
(
SELECT COUNT(FirstName) MaxCounter
FROM customer
Group By FirstName ORDER BY COUNT(FirstName) DESC LIMIT 1
)
SELECT c.FirstName
From customer c
Group BY FirstName
HAVING COUNT(FirstName) = (SELECT MaxCounter FROM cte)
There is a table:
ID City
1 Toronto
2 Toronto
3 Toronto
4 Toronto
5 NY
6 NY
How to get the following table:
City Total
NULL 6
Toronto 4
NY 2
I plan to use union:
(select city, count(*) as total from tbl group by city)
union
(select null, count(*) as total from tbl)
Is it possible to use something like to reuse the subquery:
(select city, count(*) as total from tbl group by city) tmp
union
(select null, count(*) as tmp from tbl)
Or sql already optimizes
(select city, count(*) as total from tbl group by city)
union
(select null, count(*) as total from tbl)
?
In at least MySQL 5.5 and newer, you can use the WITH ROLLUP modifier to get a total sum of the grouped elements without an extra query;
SELECT city, COUNT(*) AS total FROM tbl GROUP BY city WITH ROLLUP
city total
---------------
NY 2
Toronto 4
(null) 6
An SQLfiddle to test with.
You can't reuse the the query but you could use a view for reuse the code
create view my_view as
select city, count(*) as total
from tbl group by city
once created the view you could
select city, total
from my_view
union
select null, sum(total)
from my_view
1) Take aliases are only visible to join members and subquery. Not to union members.
2) The query as you wrote it makes little sense: aliasing tmp to a table then a scalar?
To achieve what you want to achieve, you can try using CTEs:
WITH tmp AS (SELECT city, COUNT(*) AS cnt GROUP BY city)
SELECT * FROM tmp UNION SELECT null, SUM(cnt) FROM tmp
I don't know what the performance difference would be. If you have an index on city, I doubt you will see a difference.
You use WITH ROLLUP in a subquery and then arrange the ordering in the outer query to put the rollup record on top:
SELECT *
FROM (SELECT city, COUNT(*) AS total FROM mytable GROUP BY city WITH ROLLUP) x
ORDER BY
CASE WHEN city IS NULL THEN 0 ELSE 1 END,
city
If you are planning to order the results by descending total, that's even simpler:
SELECT *
FROM (SELECT city, COUNT(*) AS total FROM mytable GROUP BY city WITH ROLLUP) x
ORDER BY total DESC
Demo on DB Fiddlde:
| city | total |
| ------- | ----- |
| | 6 |
| Toronto | 4 |
| NY | 2 |
I have records like this....
oid id
35 1
43 1
46 1
43 2
49 2
50 3
51 3
52 4
I have id=1 and 2 . I want those results which belong to both the both the ids(1,2) only.
i.e - o/p = recodrds of object_id = 43 because it is belonging to both 1 and 2.
if I use in operator then it is giving all the records (performing OR operaion)
This is a generic, fast solution to this kind of problems.
Get all IDs (in this case oid values) that staisfy our condition:
select oid from MyTalbe
where id in (1,2)
group by oid
having count (distinct id) >1
Select rows where IDs ('oid` column) IN list of IDs we need:
select oid, id from Mytable
where oid in
(select oid from MyTalbe
where id in (1,2) -- This is the same as: where id =1 or id=2
group by oid
having count (distinct id) >1
)
You can use the IN operator but then use a GROUP BY with a HAVING clause to return only those rows with a DISTINCT count of 2:
select oid
from yourtable
where id in (1,2)
group by oid
having count(distinct id) = 2;
--^ change this number to the count of ids in IN clause
See SQL Fiddle with Demo
Try this
SELECT t.oid FROM table1 t
WHERE t.oid IN (SELECT oid FROM table1 t1 WHERE t1.oid=t.oid AND t1.id = 1)
AND t.oid IN (SELECT oid FROM table1 t1 WHERE t1.oid=t.oid AND t1.id = 2)
GROUP BY oid
I have table with, folowing structure.
tbl
id name
1 AAA
2 BBB
3 BBB
4 BBB
5 AAA
6 CCC
select count(name) c from tbl
group by name having c >1
The query returning this result:
AAA(2) duplicate
BBB(3) duplicate
CCC(1) not duplicate
The names who are duplicates as AAA and BBB. The final result, who I want is count of this duplicate records.
Result should be like this:
Total duplicate products (2)
The approach is to have a nested query that has one line per duplicate, and an outer query returning just the count of the results of the inner query.
SELECT count(*) AS duplicate_count
FROM (
SELECT name FROM tbl
GROUP BY name HAVING COUNT(name) > 1
) AS t
Use IF statement to get your desired output:
SELECT name, COUNT(*) AS times, IF (COUNT(*)>1,"duplicated", "not duplicated") AS duplicated FROM <MY_TABLE> GROUP BY name
Output:
AAA 2 duplicated
BBB 3 duplicated
CCC 1 not duplicated
For List:
SELECT COUNT(`name`) AS adet, name
FROM `tbl` WHERE `status`=1 GROUP BY `name`
ORDER BY `adet` DESC
For Total Count:
SELECT COUNT(*) AS Total
FROM (SELECT COUNT(name) AS cou FROM tbl GROUP BY name HAVING cou>1 ) AS virtual_tbl
// Total: 5
why not just wrap this in a sub-query:
SELECT Count(*) TotalDups
FROM
(
select Name, Count(*)
from yourTable
group by name
having Count(*) > 1
) x
See SQL Fiddle with Demo
The accepted answer counts the number of rows that have duplicates, not the amount of duplicates. If you want to count the actual number of duplicates, use this:
SELECT COALESCE(SUM(rows) - count(1), 0) as dupes FROM(
SELECT COUNT(1) as rows
FROM `yourtable`
GROUP BY `name`
HAVING rows > 1
) x
What this does is total the duplicates in the group by, but then subtracts the amount of records that have duplicates. The reason is the group by total is not all duplicates, one record of each of those groupings is the unique row.
Fiddle: http://sqlfiddle.com/#!2/29639a/3
SQL code is:
SELECT VERSION_ID, PROJECT_ID, VERSION_NO, COUNT(VERSION_NO) AS dup_cnt
FROM MOVEMENTS
GROUP BY VERSION_NO
HAVING (dup_cnt > 1 && PROJECT_ID = 11660)
I'm using this query for my own table in PHP, but it only gives me one result whereas I'd like to the amount of duplicate per username, is that possible?
SELECT count(*) AS duplicate_count
FROM (
SELECT username FROM login_history
GROUP BY username HAVING COUNT(time) > 1
) AS t;
I have a table student like this
id | name | zip
1 | abc | 1234
2 | xyz | 4321
3 | asd | 1234
I want to get all records but zip code should not be repeated. So In case of above table records, record No 1 and 2 should be fetched. Record No. 3 will not be fetched because it has a zip code which is already in record No. 1
SELECT DISTINCT fieldName FROM tableName;
The following query will only select distinct 'zip' field.
SELECT DISTINCT zip FROM student;
SELECT * FROM tableName GROUP BY fieldName;
The following query will select all fields along with distinct zip field.
SELECT * FROM student GROUP BY zip;
TRY
SELECT DISTINCT(zip),id,name FROM student;
OR
SELECT * FROM student GROUP BY zip;
Altough in MySQL you can get away with:
SELECT *
FROM student
GROUP BY zip
I would choose:
SELECT *
FROM student t
JOIN
( SELECT MIN(id) AS minid
FROM student
GROUP BY zip
) AS grp
ON grp.minid = t.id
Since presumably the other columns are of some interest....
SELECT y.*
FROM yourTable y,
(SELECT MIN(y2.id)
FROM yourTable y2
GROUP BY y2.zip) ilv
WHERE ilv.id=y.id;
(or you could use the max-concat trick)
update
Oracle have now removed the max concat trick from the linked page - but it is described elsewhere on the internet
Try Using
Select Distinct(zip),id,name group by zip;
Is there any problem if I use as this below?
select distinct zip,name,id from student;
select id, name, distinct(zip) from student;