How to count a join in MySQL - mysql

I have 2 tables,
Cities
Id | city_name
Wanteds
Id | city_id | user_id
I want to create a table using a MySQL query that looks like the following -
City Name | Number of Wanteds
Leeds | 3
Manchester| 1
Halifax | 0
Bradford | 0
etc
where the Number of wanteds pull from the Wanteds table the total number of city_id's.
I have tried
select c.city_name, count(w.city_id) from cities c inner join wanteds w on c.id = w.city_id
but it only returns the total count for the first city.

You need to add group by clause
select c.city_name, count(w.city_id)
from cities c inner join wanteds w on c.id = w.city_id
group by c.city_name

Related

MySql query code to fetch unique data from single ID

How do i List the CUSTNUMs and NAMES of any customer who has only ordered chemical [NUMBER].
ORDERS TABLE
+---------+--------+------------+------+
| CUSTNUM | CHEMNO | DATE | QTY |
+---------+--------+------------+------+
| 123456 | 1234 | 2000-00-00 | 35 |
+---------+--------+------------+------+
CUSTOMER TABLE
+---------+-----------+-----------+
| CUSTNUM | NAME | LOCATION |
+---------+-----------+-----------+
| 123456 | AmChem | New York |
+---------+-----------+-----------+
You could join the CUSTOMER and ORDERS tables containing orders for a particular <chemno> with a subquery for the custnum that buy only a product:
SELECT
CUSTNUM, NAME
FROM
CUSTOMER c
INNER JOIN
ORDERS o ON o.CUSTNUM = c.CUSTNUM and o.CHEMNO = <chemno>
INNER JOIN
( SELECT
CUSTNUM
FROM
ORDERS
GROUP BY
CUSTNUM
HAVING
COUNT(DISTINCT CHEMNO) = 1 ) t ON t.CUSTNUM = o.CUSTNUM
I will approach this with one join between both tables, then grouping by the column CUSTNUM of the ORDERS table and finally adding the required conditions on the HAVING clause, like this:
SELECT
o.CUSTNUM,
c.NAME
FROM
ORDERS AS o
INNER JOIN
CUSTOMER AS c ON c.CUSTNUM = o.CUSTNUM
GROUP BY
o.CUSTNUM
HAVING
( COUNT(DISTINCT o.CHEMNO) = 1 AND MIN(o.CHEMNO) = <some_chemno> )
OK, slow day...
SELECT DISTINCT x.custnum
FROM orders x
LEFT
JOIN orders y
ON y.custnum = x.custnum
AND y.chemno <> x.chemno
WHERE x.chemno = 9377
AND y.order_id IS NULL;
The rest of this task has been left as an exercise for the reader

Mysql left join style sum()

I believe the answer is already there at stackoverflow but I cannot find the right keywords. So please help.
Table sales looks like this:
state | sales-representative | product | sales
NY | Mike B. | prod-A | 90
FL | David J. | prod-B | 120
FL | Mike B. | prod-A | 15
I need to get the total sales by such sales representative. Expected results for Mike B. look at this:
state | product | sales
NY | prod-A | 90
FL | prod-A | 15
NY | prod-B | 0 <--How can I get this record as well?
FL | prod-B | 0
A regular sum query returns the first 2 records. How can I get the last 2 records as well?
select state, product, sum(sales)
from sales
where sales-representative = 'Mike B.'
group by state, product
SELECT ss.state, sp.product, SUM(sr.sales)
FROM (SELECT DISTINCT state FROM sales) AS ss
CROSS JOIN (SELECT DISTINCT product FROM sales) AS sp
LEFT JOIN sales AS r
AS sr ON ss.state = s.state
AND sp.product = s.product
AND r.`sales-representative` = 'Mike B.'
GROUP BY ss.state, sp.product;
The cross join gets you every combination of state and product, and the left join gets you the specified representative's associated sales.
You can use a left join on subquery for stated and product
select t.state, t.product, sum(sales)
from table1
left join (
select t1.state, t2.product
from t1
cross join (
select product
from t1
) t2
) t on t.state = table1.state and t.product = table1.product
grooup by t.state, t.product

How I use mysql count with select query?

I have a mysql select query like this:
select r.restaurant_id, r.restaurant_name, r.city_id, c.name
from restaurants r
inner join cities c on c.id = r.city_id;
This is the result of above query:
+---------------+----------------------+---------+-------------+
| restaurant_id | restaurant_name | city_id | name |
+---------------+----------------------+---------+-------------+
| 7 | Somasiri Bake House | 5 | Mumbai |
| 8 | Indian Bake House | 7 | Chennai |
| 9 | KFC Rest | 5 | Mumbai |
| 10 | Indian t | 5 | Mumbai |
+---------------+----------------------+---------+-------------+
Now I want to display all the available cities with the number of restaurants existing to one city.
Eg: Mumbai (3), Chennai(1) and so on
I tried it like below with mysql COUN(), but it doesn't work for me.
SELECT c.name, count(r.city_id) AS count
FROM cities c
INNER JOIN restaurants r ON c.id = r.city_id;
Can anybody tell me what is the wrong with this?
Hope somebody may help me out.
Thank you.
SELECT c.name, COALESCE(count(r.city_id), 0) AS count
FROM cities c
LEFT JOIN restaurants r ON c.id = r.city_id
GROUP BY c.id
Use a simple group by if you don't want restaurant data:
select c.name, count(r.city_id) as available
from cities c
left join restaurants r on c.id = r.city_id
group by r.city_id
See SQLFiddle.
Or, if you want restaurant data too, select from cities first, then left join to other tables so cities without restaurants still get returned. Add a left join to a subquery that calculates each city's frequency:
select
r.restaurant_id,
r.restaurant_name,
c.id,
c.name,
coalesce(available, 0) available
from cities c
left join restaurants r on c.id = r.city_id
left join (select city_id, count(*) available from restaurants group by 1) a
on a.city_id = r.city_id
See SQLFiddle.
That's called a grouping or aggregate query, you need to tell it how to group your elements.
Just add
GROUP BY r.restaurant_id, r.restaurant_name, r.city_id, c.name
at the end, before your final semi-colon.

How to combine MySQL number of rows of the joined table, including 0?

I have two tables: 'company' and 'order'. The first one contains company info and the second one holds all orders made with a company. (order.company = company.ID).
I am making a query on the first table, for example all companies in the city of New York. I would like to make a join with the order table, so that it immediately shows how many orders for a company was made. I could do this with a simple JOIN query, however, it does not include 0. For example, if a company has no orders yet, it will not show up at all, while it should be in the list with 0 orders.
Desired end result:
----------------------------------------
| ID | Name | ... | Orders |
----------------------------------------
| 105 | Company A | ... | 14 |
| 115 | Company B | ... | 5 |
| 120 | Company C | ... | 0 |
| 121 | Company D | ... | 0 |
----------------------------------------
Thanks in advance!
This is a left join with aggregation:
SELECT c.ID, c.Name, count(o.company) as total
FROM companies c left outer join
orders o
on c.id = o.company
WHERE c.city = 'New York'
GROUP BY c.ID;
In MySQL, it is best to avoid subqueries in the from clause -- where possible -- because the derived table is actually created.
The COUNT() expression is counting the number of matches by counting the number of non-null values in the id field used for the join.
Try this
SELECT com.id,com.name,od.orders FROM compnay AS com
LEFT JOIN orders AS od ON od.company = com.id;
SELECT companies.ID,companies.Name ,orders.total FROM
(SELECT ID,Name FROM company where county ='NEW YORK') companies
LEFT JOIN (SELECT company,COUNT(*) as total FROM order GROUP BY company) orders
ON orders.company = companies.ID

JOIN bills ON bills.item_id = cars.id

There are two tables:
TABLE bills
item_id | price
c1 | 10000
m1 | 9000
m2 | 8000
TABLE cars
id | model
1 | toyota
2 | bmw
I need JOIN both tables, where item_id=id AND the first letter in item_id is 'c', so I need to get: c1 | 10000 | 1 | toyota
select *
from cars c
join bills b on b.item_id = concat('c', c.id)
Note that performance is orders of magnitude better (and acceptable) joining in this order, because the calculation to generate the composite key is done once per car, rather than once per car/bill combination had I joined bills first then cars.
Do it like this:
select b.*, c.*
from bills b
inner join cars c on convert(substring(b.item_id, 2, 8000), int) = c.id
where b.item_id like 'c%'