MySQL COUNT of Grouped rows [duplicate] - mysql

This question already has answers here:
Count number of unique values
(4 answers)
Closed 2 years ago.
I have following table 'tbl_pads' with one column named 'id_pad' with 6 rows:
pad_1 |
pad_1 |
pad_2 |
pad_3 |
pad_3 |
pad_3 |
With SELECT id_pad FROM tbl_pads GROUP BY id_pad
I get following rows:
pad_1 |
pad_2 |
pad_3 |
With SELECT COUNT(id_pad) AS COUNT_PADS FROM tbl_pads GROUP BY id_pad I get following rows
2 |
1 |
3 |
How can get the rows Count of the Grouped Statement? I expect the result 3

Another was of phrasing the question is that you want to get the number of different id_pad values. Once you phrase it like that, it becomes clearer that using a distinct count will work:
SELECT COUNT(DISTINCT id_pad) FROM tbl_pads

If you want to rows count of group statement in single row then you can use below query.
SELECT COUNT(id_pad) over() AS COUNT_PADS FROM tbl_pads group by id_pad limit 1;
OR
SELECT COUNT(DISTINCT id_pad) FROM tbl_pads;
And if you want multiple row based on group statement and rows count along with this then you can go with this.
SELECT COUNT(id_pad) over(), id_pad AS COUNT_PADS FROM tbl_pads group by id_pad;
See the db<>fiddle: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=97021f2b9a1cb360c1258a2bfb4e072a

If you want the number of individual id_pads.
CREATE TABLE tbl_pads
(`id_pad` varchar(5))
;
INSERT INTO tbl_pads
(`id_pad`)
VALUES
('pad_1'),
('pad_1'),
('pad_2'),
('pad_3'),
('pad_3'),
('pad_3')
;
SELECT COUNT(id_pad) AS COUNT_PADS FROM tbl_pads WHERE id_pad = 'pad_3'
| COUNT_PADS |
| ---------: |
| 3 |
db<>fiddle here

Related

How to sort records according to values provided in "IN" clause [duplicate]

This question already has answers here:
Sort the rows according to the order specified in WHERE IN clause
(6 answers)
Closed last year.
I want to fetch records from a table using the sequence provided in "IN" operator
select * from table where id in (10, 5, 30)
I want this result
ID | Name
10 | Xyz
5 | Abc
30 | Jkl
but it is actually showing this result
ID | Name
5 | Abc
10 | Xyz
30 | Jkl
IN cannot be used to determine the order of results. You need to use some kind of row value constructor:
select *
from (
select 10 as id, 1 as sort union all
select 5, 2 union all
select 30, 3
) as custom_list
join your_table on custom_list.id = your_table.id
order by custom_list.sort

Getting all entries less than max price and more than one entry from having

I'm using the Northwind database from W3 schools and my query is
SELECT Price from products group by Price having Price < max(Price)
It's currently showing no results, but how would I fix that? You can see the database here: https://www.w3schools.com/sql/trysql.asp?filename=trysql_select_having
Additionally, is it possible to get more than one entry returned from having, i.e, all rows that meet the having clause condition. For example, in the link above, only unique countries are returned that meet the condition.
EDIT: Also with the Northwind database:
SELECT *FROM Customers GROUP BY City HAVING COUNT(City) > 2;
Why does it have unexpected behaviour, i.e, not return the rows where there are more than two occurrences of the city.
try like below
SELECT Price from products
where Price < (select max(Price) from products)
if you add the max(price) to the select
DROP table if exists t;
create table t
(price int);
insert into t values (1),(2),(1),(2),(3),(10);
SELECT Price, max(price) mp from t group by Price;
you get
+-------+------+
| Price | mp |
+-------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 10 | 10 |
+-------+------+
4 rows in set (0.001 sec)
the having test is on the grouped items and is never true . To produce the correct result you need the sub query suggested by #akina.

How to group duplicated rows and count them?

my table:
id | item_id
1 | 5
2 | 5
3 | 7
4 | 2
sql:
$countWeek = $conn->query("SELECT count(item_id) FROM `myTable` GROUP BY `item_id`")->fetchColumn();
As you can see i have 2 duplicated rows with item_id = 5 i want to group these duplicated rows and output 3 rows on the count, but when i do echo $countWeek it output 1, why?
When i change the above sql to:
$countWeek = $conn->query("SELECT item_id FROM `myTable` GROUP BY `item_id`")->rowCount();
It returns the correct value, but i don't want to use rowCount() because i only need to count the rows and fetchColumn() with count() is far better in terms of speed.
You could use counct(distinct item_id)
SELECT count(distinct item_id)
FROM `myTable`

how to find duplicate count without counting original

I need to count the number of duplicate emails in a mysql database, but without counting the first one (considered the original). In this table, the query result should be the single value "3" (2 duplicate x#q.com plus 1 duplicate f#q.com).
TABLE
ID | Name | Email
1 | Mike | x#q.com
2 | Peter | p#q.com
3 | Mike | x#q.com
4 | Mike | x#q.com
5 | Frank | f#q.com
6 | Jim | f#q.com
My current query produces not one number, but multiple rows, one per email address regardless of how many duplicates of this email are in the table:
SELECT value, count(lds1.leadid) FROM leads_form_element lds1 LEFT JOIN leads lds2 ON lds1.leadID = lds2.leadID
WHERE lds2.typesID = "31" AND lds1.formElementID = '97'
GROUP BY lds1.value HAVING ( COUNT(lds1.value) > 1 )
It's not one query so I'm not sure if it would work in your case, but you could do one query to select the total number of rows, a second query to select distinct email addresses, and subtract the two. This would give you the total number of duplicates...
select count(*) from someTable;
select count(distinct Email) from someTable;
In fact, I don't know if this will work, but you could try doing it all in one query:
select (count(*)-(count(distinct Email))) from someTable
Like I said, untested, but let me know if it works for you.
Try doing a group by in a sub query and then summing up. Something like:
select sum(tot)
from
(
select email, count(1)-1 as tot
from table
group by email
having count(1) > 1
)

Group by - Overriding default behaviour of deciding row under each group in result

Extending further from this question Query to find top rated article in each category -
Consider the same table -
id | category_id | rating
---+-------------+-------
1 | 1 | 10
2 | 1 | 8
3 | 2 | 7
4 | 3 | 5
5 | 3 | 2
6 | 3 | 6
There is a table articles, with fields id, rating (an integer from 1-10), and category_id (an integer representing to which category it belongs). And if I have the same goal to get the top rated articles in each query (this should be the result):-
Desired Result
id | category_id | rating
---+-------------+-------
1 | 1 | 10
3 | 2 | 7
6 | 3 | 6
Extension of original question
But, running the following query -
SELECT id, category_id, max( rating ) AS max_rating
FROM `articles`
GROUP BY category_id
results into the following where everything, except the id field, is as desired. I know how to do this with a subquery - as answered in the same question - Using subquery.
id category_id max_rating
1 1 10
3 2 7
4 3 6
In generic terms
Excluding the grouped column (category_id) and the evaluated columns (columns returning results of aggregate function like SUM(), MAX() etc. - in this case max_rating), the values returned in the other fields are simply the first row under every grouped result set (grouped by category_id in this case). E.g. the record with id =1 is the first one in the table under category_id 1 (id 1 and 2 under category_id 1) so it is returned.
I am just wondering is it not possible to somehow overcome this default behavior to return rows based on conditions? If mysql can perform calculation for every grouped result set (does MAX() counting etc) then why can't it return the row corresponding to the maximum rating. Is it not possible to do this in a single query without a subquery? This looks to me like a frequent requirement.
Update
I could not figure out what I want from Naktibalda's solution too. And just to mention again, I know how to do this using a subquery, as again answered by OMG Ponies.
Use:
SELECT x.id,
x.category_id,
x.rating
FROM YOUR_TABLE x
JOIN (SELECT t.category_id,
MAX(t.rating) AS max_rating
FROM YOUR_TABLE t
GROUP BY t.category_id) y ON y.category_id = x.category_id
AND y.max_rating = x.rating