How to Combine GROUP CONCAT with COUNT in MySQL? - mysql

I am trying to write a query that can get result from multiple tables:
Item Category
ic_id
ic_name
1
PC
2
Laptop
3
Printer
4
Scanner
Items
i_id
i_category
i_name
1
1
Dell Optiplex
2
2
HP Probook 450
3
2
HP Probook650
4
3
HP Laserjet 402dn
5
1
Dell MT3030
Item Sale
is_id
is_date
is_customer
1
15-03-2021
John
2
16-03-2022
Jimmy
3
18-03-2023
Mark
Item Sale Detail
isd_id
isd_sale_id
isd_item
1
1
2
2
1
3
3
2
4
4
3
1
5
3
5
6
3
4
Is it possible to get combined result of GROUP CONCAT with COUNT in 1 query? Please guide me to write the query to get the desired result, I want the query result as shown below, Thanks:
Desired Result
is_id
is_date
is_customer
items
1
15-03-2021
John
Laptop: 3
2
16-03-2022
Jimmy
Printer: 1
3
18-03-2023
Mark
PC:2 , Printer: 1

If I understand correctly, this is just join but with two levels of aggregation:
select its.*, ic.categories
from item_sale its join
(select isd.isd_sale_id,
group_concat(ic_name, ':', cnt order by cnt desc) as categories
from (select isd.isd_sale_id, ic.ic_name, count(*) as cnt
from item_sale_detail isd join
items i
on isd.isd_item = i.i_id join
item_category ic
on i.i_category = ic.ic_id
group by isd.isd_sale_id, ic.ic_name
) ic
group by isd.isd_sale_id
) ic
on i.is_id = ic.isd_sale_id;

Related

MySQL find MIN() from duplicate rows

I have 3 tables like below:
Product Table
PID CODE
1 a
2 b
Price Table
PrID PID(ID from Product) UMID(ID from UOM) Price
1 1 1 10
2 1 2 5
3 2 1 10
UOM Table
UMID UM_NAME UM_RATE
1 BOX 5
2 PC 10
I want to get product with price and that uom which has min UM_RATE. For example, product CODE a has two prices but the prices are different for different uom. What I want to achieve is,
PID CODE PrID Price UM_NAME UM_RATE
1 a 1 10 BOX 5
2 b 3 10 BOX 5
Because box has min UM_RATE. I have tried the following query,
SELECT product.*, price.*, uom.um_name, MIN(uom.um_rate)
FROM product
LEFT JOIN price ON price.pid = product.pid
LEFT JOIN uom ON price.umid = uom.umid
GROUP BY product.pid
This query gives me the following result,
PID CODE PrID Price UM_NAME UM_RATE
1 a 1 10 PC 5
2 b 3 10 BOX 5
which is wrong. because UM_RATE 5 is belong to UM_NAME box.
How can I get the expected result?
use join and corelated subquery
select * from (select distinct p.*,u.UMID as uid,
u.UM_NAME,u.UM_RATE,pr.code from
price p join uom u on p.UMID=u.UMID
join product pr on pr.PID=p.PID
) a
where a.UM_RATE =(select min(UM_RATE) from
(select p.*,u.UMID as uid,
u.UM_NAME,u.UM_RATE,pr.code from
price p join uom u on p.UMID=u.UMID
join product pr on pr.PID=p.PID) t where t.code=a.code
)
prid PID UMID price uid UM_NAME UM_RATE code
1 1 1 10 1 Box 5 a
3 2 1 10 1 Box 5 b

Get most sold products with a specified one

I have a table order_detail with this informations
id_order id_product
1 2
1 3
2 2
2 4
2 5
2 3
3 2
3 1
4 2
4 3
4 1
4 6
I would like to get most sold products(the first 5 elements) with the current product let's say product id 2
I tried this but it returns one wrong result
SELECT od2.product_id, count(od2.`product_id`) FROM `ps_order_detail` od1
LEFT JOIN ps_order_detail od2 ON od1.id_order = od2.id_order where
od2.product_id != od1.product_id AND od1.product_id=2
The result should be
product_id count(od2.`product_id`)
3 3
4 2
1 1
5 1
6 1
Your query is on the right track. Mostly, you are missing a group by:
select od.product_id, count(od2.id_order) as NumTimesWith2
from ps_order_detail od left join
ps_order_detail od2
on od.id_order = od2.id_order and
od2.product_id = 2
where od.product_id <> 2
group by od.product_id
order by count(od2.id_order) desc;
If you want only one such product, then add a limit 1 to the query.
Also, this assumes that products are not repeated inside orders. If they can be, you can quickly get a better count using count(distinct od.id_order)).

MySql Count with Join

I have two tables -
Users_tag (userID,tagID)
tagId - userId
1 1
2 1
3 2
4 2
5 4
Tags (id,tagText)
id tagText
1 dog
2 cat
3 lion
4 tiger
5 chicken
I want my query to return tagId,TagText and count of each row based on userId.
Any help please...
SELECT a.id, a.tagText, COUNT(b.tagID) totalCount
FROM Tags a
LEFT JOIN users_tag b
on a.ID = b.tagID
GROUP BY a.id, a.tagText
SQLFiddle Demo

MYSQL select query using count (*)

i have a problem concerning a select query in MYSQL
i have two different tables and i want to obtain a certain result
i used COUNT method which gave me only the results (>=1)
But in reality , i want to use all counts with zero included how to do it?
My query is:
SELECT
first.subscriber_id,
second.tag_id,
COUNT(*)
FROM
content_hits first
JOIN content_tag second ON first.content_id=second.content_id
GROUP BY
second.Tag_id,first.Subscriber_id<br>
First table:Content_hits
CONTENT_ID SUBSCRIBER_ID
30 1
10 10
34 4
32 2
40 3
28 3
30 6
31 8
12 3
Second table:Content_tag
CONTENT_ID TAG_ID
1 1
2 1
3 1
4 1
5 1
6 1
7 1
8 1
9 1
10 1
11 2
12 2
13 2
14 2
Result but incomplete For example:Subsrciber6 for tag_id=1 should have a count(*)=0
subscriber_id tag_id COUNT(*)
1 1 4
2 1 7
3 1 2
4 1 1
5 1 3
7 1 2
8 1 1
9 1 1
10 1 3
1 2 2
2 2 3
3 2 2
Now that you have further elaborated on what you actually want to achieve, it can be seen that the problem is much more complex. You actually want all combinations of subscriber_id and tag_id, and then count the number of actual entries in the joined table product. whew. So here goes the SQL:
SELECT combinations.tag_id,
combinations.subscriber_id,
-- correlated subquery to count the actual hits by tag/subscriber when joining
-- the two tables using content_id
(SELECT count(*)
FROM content_hits AS h
JOIN content_tag AS t ON h.content_id = t.content_id
WHERE h.subscriber_id = combinations.subscriber_id
AND t.tag_id = combinations.tag_id) as cnt
-- Create all combinations of tag/subscribers first, before counting anything
-- This will be necessary to have "zero-counts" for any combination of
-- tag/subscriber
FROM (
SELECT DISTINCT tag_id, subscriber_id
FROM content_tag
CROSS JOIN content_hits
) AS combinations
Not sure, but is this what you want?
SELECT first.subscriber_id, second.tag_id, COUNT(*) AS c
FROM content_hits first JOIN content_tag second ON first.content_id=second.content_id
GROUP BY second.Tag_id,first.Subscriber_id HAVING c = 0

Complicated Crosstab Query Question

I have the following 2 tables:
1) Companies
ID CompanyName Abbreviation Notes
1 CompanyA CA ...
2 CompanyB CB ...
3 CompanyC CC ...
2) PlannedDeployments
ID CompanyID TypeID DepDate NumDeployed
1 1 2 09/2010 5
2 1 2 10/2010 5
3 1 3 09/2010 3
4 1 3 10/2010 3
5 1 4 10/2010 4
6 2 2 12/2010 10
7 2 4 10/2010 1
8 3 2 11/2010 6
Note that TypeID is a number between 1 and 5 describing what type of person is being deployed. For the purposes of this query, I'm interested in Type2 employees for each company and then the sum of Types 3 & 4 for each date. What I eventually want to end up with is a crosstab that looks like the following:
Crosstab
Date/Company CompanyA CompanyB CompanyC SumOfTypes3and4
09/2010 5 3
10/2010 5 8
11/2010 6
12/2010 10
The problem is that final column - the sum of Type 3 and Type 4 employees. The current crosstab that I have includes everything except that sum column and looks like the following:
TRANSFORM Sum(PlannedDeployments.NumDeployed) AS ["NumDeployed"]
SELECT PlannedDeployments.DepDate
FROM PlannedDeployments LEFT JOIN Companies ON Companies.ID=PlannedDeployments.CompanyID
WHERE PlannedDeployments.TypeID=2 AND (PlannedDeployments.DepDate Between FormFieldValue("Form", "Control") AND FormFieldValue("Form", "Control"))
GROUP BY PlannedDeployments.DepDate
PIVOT Companies.CompanyName;
The second part of that WHERE clause is just limiting the data by some form controls. Anyway - I'm having a lot of trouble getting that final column. Anyone have any ideas?
Edit: Building on the solution provided by Remou below, here's what the final query ended up looking like:
TRANSFORM Sum(PlannedDeployments.NumDeployed) AS ["NumDeployed"]
SELECT PlannedDeployments.DepDate, q.SumOfNumDeployed
FROM (SELECT PlannedDeployments.DepDate, Sum(PlannedDeployments.NumDeployed) AS SumOfNumDeployed
FROM PlannedDeployments
WHERE (((PlannedDeployments.[TypeID]) In (3,4)))
GROUP BY PlannedDeployments.DepDate) AS q
RIGHT JOIN (PlannedDeployments
INNER JOIN Companies ON PlannedDeployments.CompanyID = Companies.ID)
ON q.DepDate = PlannedDeployments.DepDate
WHERE PlannedDeployments.TypeID=2
AND (PlannedDeployments.DepDate Between FormFieldValue("Form", "Control")
AND FormFieldValue("Form", "Control"))
GROUP BY PlannedDeployments.DepDate, q.SumOfNumDeployed
PIVOT Companies.CompanyName;
You can use a subquery:
TRANSFORM Sum(PlannedDeployments.NumDeployed) AS ["NumDeployed"]
SELECT PlannedDeployments.DepDate, Sum(q.SumOfNumDeployed) AS SumOfSumOfNumDeployed
FROM (SELECT PlannedDeployments.DepDate, Sum(PlannedDeployments.NumDeployed) AS SumOfNumDeployed
FROM PlannedDeployments
WHERE (((PlannedDeployments.[TypeID]) In (3,4)))
GROUP BY PlannedDeployments.DepDate) AS q
RIGHT JOIN (PlannedDeployments
INNER JOIN Companies ON PlannedDeployments.CompanyID = Companies.ID)
ON q.DepDate = PlannedDeployments.DepDate
WHERE PlannedDeployments.TypeID=2
AND (PlannedDeployments.DepDate Between FormFieldValue("Form", "Control")
AND FormFieldValue("Form", "Control"))
GROUP BY PlannedDeployments.DepDate
PIVOT Companies.CompanyName;