I'm trying to GROUP, SORT and COUNT in a single query one of my table named 'commodities'.
Here is a simplification of my MySql table :
family sub_family name detailed_name
Agro Grains Wheat Wheat per 1 mt
Agro Grains Corn Corn per 1 mt
Agro Grains Sugar Sugar per 1 mt
Agro Fruits Apple Apple red
Agro Fruits Apple Apple green
Agro Fruits Apple Apple yellow
Agro Fruits Lemon Lemon classic
Wood Tree Lemon Lemon in logs
Wood Tree Oak Oak in logs
Wood Tree Epicea Epicea in logs
Wood Packaging Kraftliner Krafliner 3mm
I would like to :
GROUP by name
SORT by family, sub_family and lastly name
COUNTthe numbers of rows for each family, sub_family and then name (IN THE SAME sub_family)
So far I managed to do everything but COUNT in the same sub_family.
Indeed, the following query :
SELECT
TableC.family,
TableC.NbrFamily,
TableB.sub_family,
TableB.NbrSubFamily,
TableA.name,
TableA.NbrName
FROM
(
SELECT
family,
sub_family,
name,
COUNT(DISTINCT commodities.id) AS NbrName
FROM commodities GROUP BY name
) TableA
INNER JOIN
(
SELECT
sub_family,
COUNT(DISTINCT commodities.id) AS NbrSubFamily
FROM commodities GROUP BY sub_family
) TableB
ON (TableA.sub_family = TableB.sub_family)
INNER JOIN
(
SELECT
family,
COUNT(DISTINCT commodities.id) AS NbrFamily
FROM commodities GROUP BY family
) TableC
ON (TableA.family = TableC.family)
GROUP BY TableA.name
ORDER BY TableA.family,TableA.sub_family,TableA.name
which results in the following :
family NbrFamily sub_family NbrSubFamily name NbrName
Agro 7 Grains 3 Wheat 1
Agro 7 Grains 3 Corn 1
Agro 7 Grains 3 Sugar 1
Agro 7 Fruits 4 Apple 3
Agro 7 Fruits 4 Lemon 2
Wood 4 Tree 3 Lemon 2
Wood 4 Tree 3 Oak 1
Wood 4 Tree 3 Epicea 1
Wood 4 Packaging 1 Kraftliner 1
You can see that NbrName counts Lemon 2 times but I would like it to count it only 1 time because one lemon is in Fruits sub_family and the other in Tree sub_family.
[UPDATE] : Here are my desired results :
family NbrFamily sub_family NbrSubFamily name NbrName
Agro 7 Grains 3 Wheat 1
Agro 7 Grains 3 Corn 1
Agro 7 Grains 3 Sugar 1
Agro 7 Fruits 4 Apple 3
Agro 7 Fruits 4 Lemon 1
Wood 4 Tree 3 Lemon 1
Wood 4 Tree 3 Oak 1
Wood 4 Tree 3 Epicea 1
Wood 4 Packaging 1 Kraftliner 1
Just my guess of what you are asking for http://sqlfiddle.com/#!9/e9206/16
because it brings desired result:
SELECT A.family, C.NbrFamily,A.sub_family,B.NbrSubFamily,A.name,COUNT(A.Name)
FROM commodities as A
LEFT JOIN (
SELECT family,sub_family,COUNT(Name) AS NbrSubFamily
FROM commodities
GROUP BY family,sub_family
) B
ON A.sub_family = B.sub_family
AND A.family = B.family
LEFT JOIN (
SELECT family,COUNT(Name) AS NbrFamily
FROM commodities
GROUP BY family
) C
ON A.family = C.family
GROUP BY A.family,A.sub_family,A.name
ORDER BY A.id
Related
I have a table called beverages. It has the attributes name, id, and size.
How would I make a query that finds all the drinks with both size "maxi" and size "medium"
In other words. I have to find the beverages with the same name that have both sizes, as each tuple can only have one size.
So you have a table:
CREATE TABLE beverages
(id INT,
NAME VARCHAR(50),
size VARCHAR(50));
And a sample data like this:
id
name
size
1
orange
medium
1
orange
medium
1
orange
maxi
1
orange
maxi
2
soda
medium
3
cola
maxi
4
lemon tea
medium
5
soy milk
medium
5
soy milk
medium
5
soy milk
medium
5
soy milk
maxi
5
soy milk
maxi
6
coffee
maxi
7
chocolate
maxi
And you want to find any drinks that have both size so you do a query like:
SELECT id, name, GROUP_CONCAT(DISTINCT size), COUNT(DISTINCT size)
FROM beverages
GROUP BY id, name
Whereby this query returns:
id
name
group_concat(size)
count(*)
1
orange
medium,maxi
2
2
soda
medium
1
3
cola
maxi
1
4
lemon tea
medium
1
5
soy milk
medium,maxi
2
6
coffee
maxi
1
7
chocolate
maxi
1
Now you found drinks where their GROUP_CONCAT(DISTINCT size) return more than one result and COUNT(DISTINCT size) return two.
Demo fiddle
I got problem with how to display query result based by parent and child on one table
data for example:
ID
CATEGORY
PARENT
ROOT
1
FOOD & DRINK
0
NULL
2
CLOTHES
0
NULL
3
FRUIT
1
1
4
DESERT
1
1
5
PANTS
2
2
6
T-SHIRT
2
2
7
APPLE
3
1
8
BANANA
3
1
9
ICE CREAM
4
1
10
SHORTS
5
2
11
LONG T-SHIRT
6
2
and I want to sort and display to this:
ID
CATEGORY
PARENT
ROOT
2
CLOTHES
0
NULL
5
PANTS
2
2
10
SHORTS
5
2
6
T-SHIRT
2
2
11
LONG T-SHIRT
6
2
1
FOOD & DRINK
0
NULL
4
DESERT
1
1
9
ICE CREAM
4
1
3
FRUIT
1
1
7
APPLE
3
1
8
BANANA
3
1
is there any query script to display like above ?
here my code and have no luck
select
id, category, parent, root
from
tbl_menu
order by
coalesce(root,parent,id),
category
and thanks for help :)
I understand that you want to order the tree nodes depth-first. One option uses a recursive query to generate the path to each node, that you can then use for ordering:
with recursive cte as (
select t.*, cast(id as char) as path from mytable t where root is null
union all
select t.*, concat(c.path, '/', t.id)
from cte c
inner join mytable t on t.parent = c.id
)
select *
from cte
order by path
I have a table that stores id, item, food type, image and price
I want to limit the result to one of each type sold in the store e.g. dog food, cat food, dvd in descending order
Example of what is held in mysql database
table: Nunca
id item type image price
=========================================================
1 Pedigree Pouches dog food img1 $4.99
2 Cesar Classic Selection dog food img2 $3.99
3 Meaty Strips Chicken dog food img3 $2.99
4 Jelly Fish Selection cat food img4 $1.99
5 Bananas fruit img5 $2.84
6 Celery vegetables img6 $5.99
7 Apple fruit img7 $0.95
8 Pineapple Juice Soft drink img8 $0.99
9 Oranges fruit img9 $1.99
10 Cabbage vegetables img10 $0.99
11 Suicide Squad dvd img11 $12.99
The final result should look like this from the query
id item type image price
==========================================================
11 Suicide Squad dvd img11 $12.99
10 Cabbage vegetables img10 $0.99
9 Oranges fruit img9 $1.99
8 Pineapple Juice Soft drink img8 $0.99
4 Jelly Fish Selection cat food img4 $1.99
3 Meaty Strips Chicken dog food img3 $2.99
I have tried various mysql queries, but to no avail
select * from t where
id in(select max(t.id) id from t group by t.type)
order by id desc
I guess there can be window or join alternatives but this one seemed fitting for this purpose.
A typical method uses a correlated subquery:
select n.*
from nunca n
where n.id = (select max(n2.id) from nunca n2 where n2.type = n.type);
This will choose the last row of each type.
Consider the database (made up for example):
Table 'owner'
id name
1 john
2 andrew
3 peter
Table 'duck'
id name ownerID
1 duck1 1
2 duck2 1
3 duck3 1
4 duck4 2
5 duck5 2
6 duck6 3
7 duck7 3
8 duck8 1
9 duck9 3
10 duck10 3
11 duck11 1
12 duck12 2
Table 'food'
id name type duckID
1 beef meat 4
2 grass veg 8
3 lemon fruit 5
4 apple fruit 3
5 pizza snack 7
I wish to write some SQL that for each OWNER, COUNT the number of ducks which eat some kind of food. For example for owner John, there would be 2 ducks (ducks 3 and 8).
So far I am writing this code:
select owner.name, count(duck.ownerID)
from duck, food, owner
where duck.id == food.duckID
and duck.ownerID == owner.id;
I am getting the result:
Peter | 5
Any suggestions are appreciated.
This is done with an group by clause:
select owner.name, food.name, count(duck.id)
from duck, food, owner
where duck.id == food.duckID
and duck.ownerID == owner.id
group by owner.name, food.name;
This query gives you one row for each combination of owner name and food name with the number of the owner's ducks eating this food.
I have a problem regarding joining tables with group_concat. Here are the details.
table_orders:
item_cd order_id descs quantity status seq_no
1 100 coca-cola 2 A 232
2 100 pizza 1 A 233
3 101 cheeseburger 5 A 234
4 102 pepsi 4 A 235
4
table_instructions:
item_cd instruction
3 more cheese
3 less vegetable
cancelled_item_table:
quantity seq_no
1 234
1 234
1 235
Now what I want to achieve is like this:
item_cd descs quantity instructions cancelled_item
1 coca-cola 2 - -
2 pizza 1 - -
3 cheeseburger 2 more cheese, less vegetable 1,1
4 pepsi 4 - 1
This is my current query:
SELECT
ord.item_cd,
ord.order_id,
ord.descs,
ord.quantity,
GROUP_CONCAT(x.quantity) as cancelled,
GROUP_CONCAT(i.instruction) as instruct
FROM table_orders ord
LEFT JOIN cancelled_item_table x ON ord.seq_no = x.seq_no
LEFT JOIN table_instructions i ON ord.item_cd = i.item_cd
WHERE ord.status = 'A'
GROUP BY ord.order_id
and here is the output:
item_cd descs quantity instructions cancelled_item
1 coca-cola 2 - 1
2 pizza 1 - 1
3 cheeseburger 2 more cheese, more cheese,
less vegetable, less vegetable 1,1,1,1
4 pepsi 4 - 1
If you notice, cheeseburger has 2 cancelled item and 2 instruction, but the output is 4, looks like it's multiplying.
Since the join with cancelled_item_table multiplies rows, you have to join to an already grouped subquery, like this:
SELECT
ord.item_cd,
ord.order_id,
ord.descs,
ord.quantity - coalesce(x.tot,0) as quantity,
GROUP_CONCAT(i.instruction) as instruct,
x.cancelled
FROM
table_orders ord LEFT JOIN table_instructions i
ON ord.item_cd = i.item_cd LEFT JOIN
(select seq_no, count(*) as tot, GROUP_CONCAT(quantity) as cancelled
from cancelled_item_table
group by seq_no) x ON ord.seq_no = x.seq_no
WHERE ord.status = 'A'
GROUP BY ord.item_cd, ord.order_id, ord.descs, quantity