Counting the number of job orders per company - mysql

I need to write a query that returns the name of the company, and the number of the particular Job Orders that company owns.
Right now my query is like this:
SELECT c.name, cj.joborder_id
FROM company c, joborder jo, candidate_joborder cj
WHERE c.company_id=jo.company_id
AND jo.joborder_id=cj.joborder_id
AND jo.status = 'Active'
AND cj.status=700;
This returns the following table:
Name | Job Order ID
X | 1874
Y | 2003
Y | 2003
Z | 2001
What I want is:
Name | Count
X | 1
Y | 2
Z | 1
Can someone help me with this?
Thanks

The query you want is the following:
SELECT c.name,
count(cj.joborder_id)
FROM company c,
joborder jo,
candidate_joborder cj
WHERE c.company_id=jo.company_id
AND jo.joborder_id=cj.joborder_id
AND jo.status = 'Active'
AND cj.status=700
GROUP BY c.name;
I'd suggest the following references for SQL aggregation and specifically group by and count:
http://www.youtube.com/watch?v=fSH1jpV2nNs
http://www.w3resource.com/sql/aggregate-functions/count-with-group-by.php

use COUNT() and GROUP BY clause,
SELECT c.name, COUNT(cj.joborder_id) TotalCount
FROM company c, joborder jo, candidate_joborder cj
WHERE c.company_id=jo.company_id
AND jo.joborder_id=cj.joborder_id
AND jo.status = 'Active'
AND cj.status=700
GROUP BY c.name
using ANSI JOIN
SELECT c.name,
COUNT(cj.joborder_id) TotalCount
FROM company c
INNER JOIN joborder jo
ON c.company_id = jo.company_id
INNER JOIN candidate_joborder cj
ON jo.joborder_id = cj.joborder_id
WHERE jo.status = 'Active' AND
cj.status=700
GROUP BY c.name

SELECT DISTINCT(c.name), COUNT(cj.joborder_id)
FROM company c, joborder jo, candidate_joborder cj
WHERE c.company_id=jo.company_id
AND jo.joborder_id=cj.joborder_id
AND jo.status = 'Active'
AND cj.status=700
GROUP BY c.name

Related

mysql count() with two tables and don't repeat more than 2 row

I have two tables.
Table: employees
Table: employee_roles
I'd like to show a list of all employees where they don't have more than 2 or equal employee_id.
I mean something like this I need to show:
How can I do the query? I used this query but it doesn't work. Also with the conditional WHERE name like '%'.
SELECT COUNT(id_employee), name
FROM employees
WHERE name LIKE '%' AND id_employee NOT IN
(SELECT employee_id
FROM employee_roles);
If you want employees with one role, then you can use aggregation:
select id_employee
from employee_roles
group by id_employee
having count(*) = 1;
If you want employees with 0 or 1 role, then you need to bring in the employees with no roles, using a left join:
select e.id_employee, e.name
from employees e left join
employee_roles er
on e.id_employee = er.id_employee
group by e.id_employee, e.name
having count(er.id_employee) <= 1;
If you want to count them, use a subquery:
select count(*)
from (select e.id_employee, e.name
from employees e left join
employee_roles er
on e.id_employee = er.id_employee
group by e.id_employee, e.name
having count(er.id_employee) <= 1
) e
Try the following
first option using left join
select
name
from
(
select
id_employee,
name
from employees e
left join employee_roles er
on e.id_employee = er.employee_id
group by
id_employee,
name
having count(employee_id) <= 1
) val
Second option usin union all
select
name
from employees e
where not exists (
select
employee_id
from employee_roles er
where e.id_employee = er.employee_id
)
union all
select
name
from employee_roles er
join employees e
on e.id_employee = er.employee_id
group by
name
having count(employee_id) = 1
output:
| name |
| ----- |
| Poul |
| Erick |
| Joy |
| Smith |
You need to join the tables, then use COUNT(*) and GROUP BY. Then you can check if the count is 1 to filter out employees with multiple roles.
SELECT name
FROM employees AS e
JOIN employee_roles AS r ON e.id_employee = r.id_employee
GROUP BY e.id_employee
HAVING COUNT(*) = 1

Intersection in mysql for multiple values

The intersect keyword is not available in mysql. I want to know how to implement the following in mysql db. My tables are:
customer(cid,city,name,state)
orders(cid,oid,date)
product(pid,price,productname)
lineitem(lid,pid,oid,totalquantity,totalprice)
I want the products bought by all the customers of a particular city 'X'. i.e. every customer in city 'x' should have bought the product. I managed to select the oid's and the pid's of customers living in that particular city. Now I should select the pid's which is present in all the oid's.
Example.
Oid Pid
2400 1
2400 2
2401 3
2401 1
2402 1
2403 1
2403 3
The answer from the above input should be 1 because it is present in all oid's. The query which I used to get the oid's and pid's:
select t.oid,l.pid
from lineitem l
join (select o.oid,c1.cid
from orders o
join (select c.cid
from customer c
where c.city='X') c1
where o.cid=c1.cid) t on l.oid=t.oid
Now I need to intersect all the oid's and get the result.The query should not be dependent on data.
Try:
select pid, count(*)
from (select t.oid, l.pid
from lineitem l
join (select o.oid, c1.cid
from orders o
join (select c.cid from customer c where c.city = 'X') c1
where o.cid = c1.cid) t
on l.oid = t.oid) x
group by pid
having count(*) = (select count(*)
from (select distinct oid
from lineitem l
join (select o.oid, c1.cid
from orders o
join (select c.cid
from customer c
where c.city = 'X') c1
where o.cid = c1.cid) t
on l.oid = t.oid) y) z
I think you can achieve what you want by using IN

Subquery select as filed

I tried to make a subselect in a MySQL selct statement e.g. like the following one:
SELECT
c.id AS id,
c.name AS name,
(SELECT count(*) FROM orders o WHERE o.user_id = c.id) AS order_count
FROM
customers c
Any ideas why this does not work in MySQL?
Is it possible to do something like that in MySQL?
Tried it in Version 3.23.58 and 5.1.60.
Thanks in advance!
You missed , after name, try this:
SELECT
c.id AS id,
c.name AS name,
(SELECT count(*) FROM orders o WHERE o.user_id = c.id) AS order_count
FROM
customers c
In order to avoid these sorts of errors (like missing commas), I like to write queries out like this...
SELECT c.id
, c.name
, COALESCE(COUNT(o.user_id),0) order_count
FROM customers c
LEFT
JOIN orders o
ON o.user_id = c.id
GROUP
BY c.id;
SELECT
c.id AS id ,
c.name AS name ,
(SELECT count(*)
FROM orders o
WHERE o.user_id = c.id) AS order_count
FROM
customers c
Use ',' after every column
Another method using joins
SQLFIDDLE DEMO
Sample data:
ID NAME
1 john
2 jack
3 kelly
ID USERID
10 1
11 2
12 1
13 3
14 2
15 3
16 2
17 4
18 1
Query:
SELECT count(o.userid), c.id, c.name
FROM cusomter c
LEFT JOIN orders o
ON c.id = o.userid
GROUP BY c.id
;
You may add case when to represent null as a 0 if a customer doesen't have any orders. You choice.
Results:
COUNT(O.USERID) ID NAME
3 1 john
3 2 jack
2 3 kelly

Find products that are sold at a price less than mine

I have a table of products, suppliers and prdtFrn as follows:
suppliers:
fid , name
1 | 'Andrey'
2 | 'lucas'
products:
pid , name
1 | 'X'
2 | 'Y'
prdtFrn:
pid , fid , price
---------------- supplier 'andrey'
1 | 1 | 19.00
2 | 1 | 16.00
----------------- supplier 'lucas'
1 | 2 | 14.00
2 | 2 | 18.00
And I am looking for a SQL query that will return all products that are sold at a price less than mine (andrey). In this example, I would want to get product "X", because lucas is selling it for less than I am.
A lot of the other answers seem complicated, but the answer is simple:
select distinct p1.*
from prdtfrn p1
join prdtfrn p2 on p1.pid = p2.pid and p2.fid != 1 and p2.price < p1.price
where p1.fid = 1; // fid=1 is known to be 'Audrey'
This query lists all products that are sold cheaper elsewhere.
Just select from the prdtFrn table twice. From there, the query is straightforward.
I've included an untested example below. A corresponds to the competitors' products and B corresponds to yours.
SELECT
suppliers.name,
A.pid,
A.price
FROM
prdtfrn AS A,
prdtfrn AS B,
suppliers
WHERE
A.price < B.price
AND A.pid = B.pid
AND B.fid = 1
AND A.fid = suppliers.fid;
I assumed that you are comparing to many suppliers (not only to lucas) so this is my query. Try this one:
SELECT e.name,
g.name,
f.price
FROM suppliers e INNER JOIN prdtFrn f ON
e.fid = f.fid
INNER JOIN products g ON
f.pid = g.pid
WHERE e.name <> 'Andrey' AND -- this selects all products which is not yours
f.pid IN -- the selected products should match your products
(SELECT c.pid -- this subquery selects all your products
c.name,
b.price
FROM suppliers a INNER JOIN prdtFrn b ON
a.fid = b.fid
INNER JOIN products c ON
b.pid = c.pid
WHERE a.name = 'Audrey') d AND
f.price < d.price -- product is less than yours
Here is a query to get the info you're looking for. As there might be products that other suppliers have on sale and you don't, I thought you might be interested in finding those out too.
This is the query that you're asking for (without the products other suppliers have and you don't):
select sp2.pid, p.name as ProductName, sp2.price, s2.name as SupplierName
from prdtFrn sp2 join (
select sp.pid, sp.price from suppliers s
join prdtFrn sp on sp.fid = s.fid
where s.name = 'Andrey'
) as AndreysProducts
on AndreysProducts.pid = sp2.pid
join products p on sp2.pid = p.pid
join suppliers s2 on s2.fid = sp2.fid
where sp2.price < AndreysProducts.price
Example
This is the query that you might be interested in (with the products other suppliers have and you don't):
select sp2.pid, p.name as ProductName, sp2.price, s2.name as SupplierName
from prdtFrn sp2 left join (
select sp.pid, sp.price from suppliers s
join prdtFrn sp on sp.fid = s.fid
where s.name = 'Andrey'
) as AndreysProducts
on AndreysProducts.pid = sp2.pid
join products p on sp2.pid = p.pid
join suppliers s2 on s2.fid = sp2.fid
where sp2.price < AndreysProducts.price or AndreysProducts.pid is null
Example

Counting and Joins

I have a query like this:
SELECT c.id, c.name, f.name
FROM companies c
INNER JOIN facilities f ON c.id = f.company
ORDER BY c.name DESC, f.name
I also want to retrieve a COUNT() of all work_orders (a table) that are approved (a column containing 0 or 1) for each row (each facility).
e.g, SELECT COUNT(*) FROM work_orders w WHERE w.facility = f.id AND w.approved = 1
The result should look like
company | facility | count
--------------------------
goog | ohio | 2
goog | cali | 0
tekk | cupertin | 0
As kind of a follow up, i'd also like to add another count column where w.approved = 0
SELECT c.id, c.name, f.name, COUNT(w.id) AS work_orders
FROM companies c
INNER JOIN facilities f ON c.id = f.company
-- LEFT JOIN used in case there are facilities with no work orders
LEFT JOIN work_orders w ON f.id = w.facility AND w.approved = 1
GROUP BY c.id, c.name, f.name
ORDER BY c.name DESC, f.name
To do multiple counts (approved or not):
SELECT c.id, c.name, f.name,
wapp.wo AS approved_work_orders,
wnapp.wo AS non_approved_work_orders,
FROM companies c
INNER JOIN facilities f ON c.id = f.company
LEFT JOIN (SELECT facility, COUNT(*) AS wo FROM work_orders WHERE approved=1 GROUP BY facility) wapp ON f.id = wapp.facility
LEFT JOIN (SELECT facility, COUNT(*) AS wo FROM work_orders WHERE approved=0 GROUP BY facility) wnapp ON f.id = wnapp.facility
ORDER BY c.name DESC, f.name
It looks like you just need a grouping on c.id and an if statement
SELECT c.id, c.name, f.name, IF(count(0)>0,1,0)
FROM companies c
INNER JOIN facilities f ON c.id = f.company
LEFT JOIN work_orders w ON w.facility = f.id
GROUP BY f.id
ORDER BY c.name DESC, f.name