Mysql query to select count a column distinct? - mysql

I using MySql and I have...
orders
+--------+---------+-------------+
| ID | PRO_ID | CUS_ID |
+--------+---------+-------------+
| 1 | 1 | 2 |
| 2 | 1 | 79 |
| 3 | 1 | 6 |
| 4 | 2 | 41 |
| 5 | 2 | 28 |
| 6 | 2 | 33 |
| 7 | 3 | 2 |
| 8 | 4 | 9 |
| 9 | 4 | 23 |
| 10 | 5 | 43 |
| 11 | 5 | 45 |
| 12 | 5 | 78 |
| 13 | 5 | 67 |
| 14 | 6 | 12 |
| 15 | 6 | 95 |
How to get 5 top PRO_ID and their count. Example
+---------+-------------+
| PRO_ID | COUNT |
+---------+-------------+
| 5 | 4 |
| 1 | 3 |
| 2 | 3 |
| 4 | 2 |
| 6 | 2 |
my orders table have 2 millions rows, i need a query faster. Thanks for any help!

Apply indexing for that particular field and go on with this query....i hope it will give you better performance
select PRO_ID,count(PRO_ID) as prod_count
from orders
group by PRO_ID
order by prod_count desc
limit 5

You can do like:
select PRO_ID, COUNT(*) as total
from test
group by PRO_ID
ORDER BY total desc, PRO_ID
limit 5
here is fiddle

select PRO_ID,count(PRO_ID) as count
from orders
group by PRO_ID
order by count desc
limit 5
If the query seems to slow then try adding index on your table

Related

How to work out total distinct values minus grouped distinct values in MySQL

Given the sample table of:
+----+----------+---------+------+
| id | userName | storeId | cost |
+----+----------+---------+------+
| 1 | foo | 1 | 10 |
| 2 | bar | 1 | 10 |
| 3 | baz | 5 | 5 |
| 4 | baz | 3 | 20 |
| 5 | qux | 1 | 5 |
| 6 | qux | 4 | 20 |
| 7 | qux | 15 | 30 |
| 8 | qux | 17 | 40 |
| 9 | qux | 3 | 5 |
| 10 | quux | 6 | 20 |
+----+----------+---------+------+
I would like to work out how many people purchased at each store and how many did not. I want the report to display the results grouped by store.
I know the statement select storeId, count(distinct username) as total from purchases group by storeId provides me with how many people purchased in each store, but I want to subtract the result of the query select count(distinct userName) from purchases; in another column. I would expect the sample output to display as follows.
+---------+-----------+--------------+
| storeId | purchased | notPurchased |
+---------+-----------+--------------+
| 1 | 3 | 2 |
| 3 | 2 | 3 |
| 4 | 1 | 4 |
| 5 | 1 | 4 |
| 6 | 1 | 4 |
| 15 | 1 | 4 |
| 17 | 1 | 4 |
+---------+-----------+--------------+
You can use NOT condition with IN() function
As long a subse3lect gives back only only one,
you can use following
SELECT
storeId,
COUNT(DISTINCT username) AS total,
((SELECT
COUNT(DISTINCT userName)
FROM
purchases) - COUNT(DISTINCT username)) notPurchased
FROM
purchases
GROUP BY storeId
storeId | total | notPurchased
------: | ----: | -----------:
1 | 3 | 2
3 | 2 | 3
4 | 1 | 4
5 | 1 | 4
6 | 1 | 4
15 | 1 | 4
17 | 1 | 4
db<>fiddle here

select sum of product price for every 1 id productcategory

i want to find solution for my query problem. I need to find the SUM of all priceProduct*quantity and separated with each of productcategory. I have already made a query, but it takes longer time to executed it. this is my query,
SELECT
pb.ProductCategoryID,
pb.ProductCategoryDescription,
(SELECT
SUM((SELECT pd.HPP FROM `price details` pd WHERE pd.ProductID = pdt.ProductID ORDER BY pd.PriceDetailID DESC LIMIT 1)*
(SELECT StockProductBallance FROM `stock product` sp WHERE sp.ProductID = pdt.ProductID ORDER BY sp.StockProductID DESC LIMIT 1))
FROM product pdt
WHERE pdt.ProductCategoryID = pb.ProductCategoryID
) AS Total
FROM `product category` pb
GROUP BY pb.ProductCategoryID
this my example table
table product:
+------+-------+
| id_p | id_pc |
+------+-------+
| 1 | 3 |
| 2 | 4 |
| 3 | 3 |
| 4 | 4 |
+------+-------+
table productcategory:
+-------+---------+
| id_pc | pc_name |
+-------+---------+
| 3 | new_pc |
| 4 | old_pc |
+-------+---------+
table price details:
+---------------+------+-----+
| PriceDetailID | id_p | hpp |
+---------------+------+-----+
| 1 | 1 | 100 |
| 2 | 1 | 110 |
| 3 | 1 | 120 |
| 4 | 2 | 200 |
| 5 | 2 | 210 |
| 6 | 2 | 220 |
+---------------+------+-----+
table stockProduct:
+-----------------+------+---------------+
| id_stockProduct | id_p | stockballance |
+-----------------+------+---------------+
| 1 | 1 | 10 |
| 2 | 1 | 11 |
| 3 | 1 | 12 |
| 4 | 2 | 20 |
| 5 | 2 | 21 |
| 6 | 2 | 22 |
+-----------------+------+---------------+
Really need your help guys, for better query..

How can I order multiple columns in mysql?

I have this table in my mysql:
| id | category_id | region_id | score |
+----+-------------+-----------+-------+
| 1 | 1 | 1 | 78 |
| 2 | 1 | 2 | 65 |
| 3 | 1 | 3 | 98 |
| 4 | 1 | 4 | 45 |
| 5 | 1 | 5 | 78 |
| 6 | 1 | 1 | 98 |
| 7 | 1 | 2 | 32 |
| 8 | 1 | 3 | 56 |
| 9 | 1 | 4 | 89 |
| 10 | 1 | 5 | 65 |
+----+-------------+-----------+-------+
I want to get the 5 latest id but order my result table base on region id so I used this code
SELECT *
FROM tb_scores
WHERE category_id = 1
ORDER
BY id DESC
, region_id ASC
LIMIT 5
but the result only sorted the id as desc but not the region_id as ASC..to explain briefly I want this kind of result.
| id | category_id | region_id | score |
+----+-------------+-----------+-------+
| 6 | 1 | 1 | 98 |
| 7 | 1 | 2 | 32 |
| 8 | 1 | 3 | 56 |
| 9 | 1 | 4 | 89 |
| 10 | 1 | 5 | 65 |
+----+-------------+-----------+-------+
try this:
SELECT *
FROM (SELECT *
FROM tb_scores
WHERE category_id = 1
ORDER BY id DESC,region_id ASC LIMIT 5) t
ORDER BY region_id
get your data in subquery and apply order by region_id on the subquery result.

MySQL - How to use GROUP BY / ORDER BY with "nested" dataset?

My (sub)query results in following dataset:
+---------+------------+-----------+
| item_id | version_id | relevance |
+---------+------------+-----------+
| 1 | 1 | 30 |
| 1 | 2 | 30 |
| 2 | 3 | 22 |
| 3 | 4 | 30 |
| 4 | 5 | 18 |
| 3 | 6 | 30 |
| 2 | 7 | 22 |
| 1 | 8 | 30 |
| 5 | 9 | 48 |
| 4 | 10 | 18 |
| 5 | 11 | 48 |
| 3 | 12 | 30 |
| 3 | 13 | 31 |
| 4 | 14 | 19 |
| 2 | 15 | 22 |
| 1 | 16 | 30 |
| 5 | 17 | 49 |
| 2 | 18 | 22 |
+---------+------------+-----------+
18 rows in set (0.00 sec)
Items and versions are stored in separate InnoDB-tables.
Both tables have auto-incrementing primary keys.
Versions have a foreign key to items (item_id).
My question: How do I get a subset based on relevance?
I would like to fetch the following subset containing the most relevant versions:
+---------+------------+-----------+
| item_id | version_id | relevance |
+---------+------------+-----------+
| 1 | 16 | 30 |
| 2 | 18 | 22 |
| 3 | 13 | 31 |
| 4 | 14 | 19 |
| 5 | 17 | 49 |
+---------+------------+-----------+
It would be even more ideal to fetch the MAX(version_id) in case of equal relevance.
I tried grouping, joining, ordering, etcetera in many ways but I'm not able to get the desired result.
Some of the things I tried is:
SELECT item_id, version_id, relevance
FROM (subquery) a
GROUP BY item_id
ORDER BY relevance DESC, version_id DESC
But of course the ordering happens after the fact, so that both relevance and MAX(version_id) information is lost.
Please advice.
This is how you can do this:
SELECT t1.item_id, max(t1.version_id), t1.relevance FROM t t1
LEFT JOIN t t2 ON t1.item_id = t2.item_id AND t1.relevance < t2.relevance
WHERE t2.relevance IS NULL
GROUP BY t1.item_id
ORDER BY t1.item_id, t1.version_id
Output:
| ITEM_ID | VERSION_ID | RELEVANCE |
|---------|------------|-----------|
| 1 | 16 | 30 |
| 2 | 18 | 22 |
| 3 | 13 | 31 |
| 4 | 14 | 19 |
| 5 | 17 | 49 |
Fiddle here.

join with a group by?

i have a table called rc_language_type_table with:
id language
1 english
2 Xhosa
3 afrikaans
etc
then i have a table rc_language_type_assoc_table with:
profile_id | language_type_id |
+------------+------------------+
| 3 | 1 |
| 13 | 1 |
| 15 | 1 |
| 16 | 1 |
where i have profiles and each profile is connected to a language id in a 1 to many
so then i did:
select *,count(*) from rc_language_type_assoc_table group by language_type_id;
+------------+------------------+----------+
| profile_id | language_type_id | count(*) |
+------------+------------------+----------+
| 3 | 1 | 96 |
| 3 | 2 | 19 |
| 3 | 3 | 18 |
| 64 | 4 | 51 |
| 94 | 5 | 10 |
| 37 | 6 | 26 |
| 3 | 7 | 21 |
| 3 | 8 | 4 |
| 3 | 9 | 6 |
| 88 | 10 | 4 |
| 3 | 11 | 3 |
+------------+------------------+----------+
what i want now is: instead having the language_type_id i want to display the actual language...how would i do this please???
i tried:
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
group by language_type_id
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id;
but i get a syntax error...
please help??
thank you
GROUP BY should be "after" the WHERE statement and not before
select *, count(*)
from rc_language_type_assoc_table, rc_language_type_table
where rc_language_type_assoc_table.language_type_id = rc_language_type_table.id
group by language_type_id ;