I have a table with a column status:
1 row with status_1
3 rows with status_2
2 rows with status_3
7 rows with status_4
I want to write a query that gets all available statuses, groups them, and get the number of occurences then fetch the data as follows:
Status 1: 1
Status 2: 3
Status 3: 2
Status 4: 7
NB: The statuses are not already known. And we are not talking about DISTINCT or GROUP BY to count the number of unique values (it must be a separate number for each status)
SELECT status, count(*) count
FROM your_table
GROUP BY status;
See MySQL Group BY tutorial
According to data you seem want GROUP BY with COUNT() only
select status, count(*) as noofoccurences
from table t
group by status;
I have table with, following structure.
id name
1 john
2 ana
3 john
4 ana
5 peter
6 ana
7 Abrar
8 Raju
Duplicate entries in the table are as follows
john(2) duplicate
ana(3) duplicate
The names which are duplicates are john and ana.
My question is how would I count the records in total which are duplicate here it is '5' records
Note : I also followed the similar question in community but it explains how we can add the number of duplicates exists for that particular name in the table and adds up the third column in table representing the duplicates records with same name but in my case I wanted to know the number of all duplicates exist in the table (here the result of the query is just number "5") irrespective of the names.
Just take a count subquery on the query you already have in mind (or perhaps have already written):
SELECT SUM(cnt) AS total_duplicates
FROM
(
SELECT COUNT(*) AS cnt
FROM yourTable
GROUP BY name
HAVING COUNT(*) > 1
) t;
Demo
We have following table with columns:
CategoryId | CategoryName with CategoryId as primary-key.
We have following data:
0 Other
1 Bumper
2 Door
3 Roof
4 Fender
I use select * from these table and i get rows in the above sequence only i.e. 0 first and 4 at last.
Is there any way I can get 0 at last? i.e. 1,2,3,4,0?
select * from yourtable order by CategoryId=0,CategoryId
You can use arbitrary expressions in an order by clause. By first ordering by CategoryId=0, you get all records for which that is false, followed by records (obviously only one, since it is the primary key) for which it is true. Then each of those sets of records are sorted by CategoryId.
Is it possible to sort in MySQL by "order by" using a predefined set of column values (ID) like order by (ID=1,5,4,3) so I would get records 1, 5, 4, 3 in that order out?
UPDATE: Why I need this...
I want my records to change sort randomly every 5 minutes. I have a cron task to update the table to put different, random sort order in it.
There is just one problem! PAGINATION.
I will have visitors who come to my page, and I will give them the first 20 results. They will wait 6 minutes, go to page 2 and have the wrong results as the sort order has already changed.
So I thought that if I put all the IDs into a session on page 2, we get the correct records even if the sorting had already changed.
Is there any other better way to do this?
You can use ORDER BY and FIELD function.
See http://lists.mysql.com/mysql/209784
SELECT * FROM table ORDER BY FIELD(ID,1,5,4,3)
It uses Field() function, Which "Returns the index (position) of str in the str1, str2, str3, ... list. Returns 0 if str is not found" according to the documentation. So actually you sort the result set by the return value of this function which is the index of the field value in the given set.
You should be able to use CASE for this:
ORDER BY CASE id
WHEN 1 THEN 1
WHEN 5 THEN 2
WHEN 4 THEN 3
WHEN 3 THEN 4
ELSE 5
END
On the official documentation for mysql about ORDER BY, someone has posted that you can use FIELD for this matter, like this:
SELECT * FROM table ORDER BY FIELD(id,1,5,4,3)
This is untested code that in theory should work.
SELECT * FROM table ORDER BY id='8' DESC, id='5' DESC, id='4' DESC, id='3' DESC
If I had 10 registries for example, this way the ID 1, 5, 4 and 3 will appears first, the others registries will appears next.
Normal exibition
1
2
3
4
5
6
7
8
9
10
With this way
8
5
4
3
1
2
6
7
9
10
There's another way to solve this. Add a separate table, something like this:
CREATE TABLE `new_order` (
`my_order` BIGINT(20) UNSIGNED NOT NULL,
`my_number` BIGINT(20) NOT NULL,
PRIMARY KEY (`my_order`),
UNIQUE KEY `my_number` (`my_number`)
) ENGINE=INNODB;
This table will now be used to define your own order mechanism.
Add your values in there:
my_order | my_number
---------+----------
1 | 1
2 | 5
3 | 4
4 | 3
...and then modify your SQL statement while joining this new table.
SELECT *
FROM your_table AS T1
INNER JOIN new_order AS T2 on T1.id = T2.my_number
WHERE ....whatever...
ORDER BY T2.my_order;
This solution is slightly more complex than other solutions, but using this you don't have to change your SELECT-statement whenever your order criteriums change - just change the data in the order table.
If you need to order a single id first in the result, use the id.
select id,name
from products
order by case when id=5 then -1 else id end
If you need to start with a sequence of multiple ids, specify a collection, similar to what you would use with an IN statement.
select id,name
from products
order by case when id in (30,20,10) then -1 else id end,id
If you want to order a single id last in the result, use the order by the case. (Eg: you want "other" option in last and all city list show in alphabetical order.)
select id,city
from city
order by case
when id = 2 then city else -1
end, city ASC
If i had 5 city for example, i want to show the city in alphabetical order with "other" option display last in the dropdown then we can use this query.
see example other are showing in my table at second id(id:2) so i am using "when id = 2" in above query.
record in DB table:
Bangalore - id:1
Other - id:2
Mumbai - id:3
Pune - id:4
Ambala - id:5
my output:
Ambala
Bangalore
Mumbai
Pune
Other
SELECT * FROM TABLE ORDER BY (columnname,1,2) ASC OR DESC
I have a table like this:
id number otherfields
-------------------------------------------
664 48 aaa
665 49 bbb
666 55 ccc
667 48 ddd
My query groups by the number field, and I want it to pick the first (lowest) id, so that the data comes out like ccc,aaa,bbb (when ordered by number). However I'm getting ccc,ddd,bbb - in other words, it's picking row #667 instead of #664 for the number 48.
Oddly, this only happens on the live server; on localhost I get it the correct way even though the table is exactly the same (exported from localhost, imported onto server).
Is it possible to ensure that the GROUP BY clause picks the first ID?
No, it is not possible in MySQL. You have to use a join.
SELECT id, number, otherfields FROM table
WHERE id in (SELECT min(id) FROM table GROUP BY number)
SQL-92 version.
SELECT
id, number, otherfields
FROM
table t
join (SELECT min(id) as id, number FROM table GROUP BY number) sq --subquery
on t.id = sq.id