MySQL query to print data from two tables - mysql

I need help with writing a MySQL query to print the respective department names and number of Employee for all departments in the Department table.
Expected output:
Executive 2
Technical 2
Production 1

A join command would be what you are looking for.
select transaction.username, transaction.transactiondate, products.price, products.quantity, products.description
from transaction, products
where products.productid = transaction.productid
and products.productid = IDHERE

I assume you have a simple table which structure as below show:
+--------+------+
| name | dep |
+--------+------+
| frank | IT |
| jack | IT |
| Sissel | FA |
| Li | FA |
| Mok | PM |
+--------+------+
You have three department maybe more, you can simple use count to fetch number of employee for all departments. and if you use group by dep you will get each number by you expect .
SELECT dep, count(*) FROM user_table GROUP BY dep;
And then you got:
+------+----------+
| dep | count(*) |
+------+----------+
| FA | 2 |
| IT | 2 |
| PM | 1 |
+------+----------+
Hope, that's all your need~

SELECT a.name as department_name, count(b.id) as num_of_employees
FROM department a INNER JOIN employee b ON a.dept_id = b.dept_id
GROUP BY a.dept_id

Related

Do the people in the table satisfy the following condition

I have the following tables:
Student Table
| id | name | gender|
|----|----------|-------|
| 1 | April | F |
| 2 | Jane | F |
| 3 | Joe | M |
| 4 | Mike | M |
Project Table
| project_id | student_id | project_name|
|------------|------------|-------------|
| 101 | 1 | Alpha |
| 101 | 2 | Alpha |
| 101 | 3 | Alpha |
| 102 | 2 | M |
| 102 | 4 | M |
| 103 | 1 | Beta |
| 103 | 3 | Beta |
Assume there are much more students and project ids.
Multiple students can work in the same project.
My question is, having the tables above, how can I check how many students who worked together on 2 or more projects? So in the example above, students with id 1 and 3 worked together in project Alpha and Beta.
My code so far is
SELECT * FROM student s
JOIN project s ON student.id = project.project_id
I know I want to join both tables by the column they share (which is the student id) but I have no idea what to do after. I am new to SQL barely a week in learning and would appreciate the most help.
Use a self join and aggregation:
select p1.student_id, p2.student_id, count(*) as num_projects
from projects p1 join
projects p2
on p1.project_id = p2.project_id and
p1.student_id < p2.student_id
group by p1.student_id, p2.student_id
having count(*) > 1
order by count(*) desc;
Consider:
select count(*)
from (
select 1
from projects p1
inner join projects p2
on p2.project_id = p1.project_id and p2.student_id < p1.student_id
group by p1.student_id, p2.student_id
having count(*) > 1
) t
The inner query self-joins the project table and generates unique tuples of students that worked on the same project; the having clause filters on tuples that worked together on more than one project.
The outer query just counts the number of tuples.

Join Table B to Table A only if entry in Table B equals entry in Table C

I have 3 tables. clients, sales and potential_sales.
The basic structure is as follows:
Clients Table:
+-----------+-------+----------------+
| client_id | name | address |
+-----------+-------+----------------+
| 1 | john | 12 blue ave |
| 2 | paul | 34 green lane |
| 3 | peter | 69 yellow road |
+-----------+-------+----------------+
Potential Sales Table:
+----------+------------+---------------------+
|product_id | client_id | received_free_promo |
+-----------+------------+---------------------+
| 3 | 1 | 1 |
| 4 | 2 | 0 |
| 5 | 2 | 1 |
+-----------+------------+---------------------+
Sales:
+----------+-----------+-----------+
| sales_id | client_id | product_id |
+----------+-----------+------------+
| 1 | 2 | 4 |
| 2 | 43 | 4 |
| 3 | 2 | 5 |
| 4 | 18 | 93 |
+----------+-----------+------------+
I want to join clients and potential_sales tables ONLY IF
1) received_promo equals 1 AND
2) they actually bought the promo package (i.e. the product_id for the potential sale has an entry into the sales table ). If they didn't eventually buy the free_promo product then I do not want to join the clients and potential_sales table at all. This is important - I can't simply JOIN to figure it out because this is only a small part of a bigger query and I can't afford to JOIN for no reason.
(Here is how I would like it to work. It's mainly pseudo-code to describe what I want to happen)
SELECT
c.*
FROM
clients c
LEFT JOIN potential_sales ps ON ps.client_id=c.id
LEFT JOIN sales ps ON s.product_id=ps.product_id
IF(s.sales_id) JOIN potential_sales ps ON ps.client_id=c.id
How do I do this in MySQL? I haven't come close to a solution. Please help!
Try this:
SELECT A.*, B.product_id, B.received_free_promo
FROM Clients A JOIN
(SELECT * FROM PotentialSales
WHERE received_free_promo=1) B
ON A.client_id=B.client_id
WHERE EXISTS (SELECT 1 FROM Sales C
WHERE A.client_id=C.client_id
AND B.product_id=C.product_id);
See Demo on SQL Fiddle.
What you are missing is the EXISTS clause:
SELECT
C.*,
P.*
FROM
Clients AS C
INNER JOIN PotentialSales AS P ON C.client_id = P.client_id
WHERE
P.received_free_promo = 1 AND
EXISTS (
SELECT
'the client already sold that product'
FROM
Sales AS S
WHERE
S.client_id = C.client_id AND
S.product_id = P.product_id)
Try this..." select * from client as c natural join potential as p join sales as s on p.product_id = s.product_id where received_promo = 1". select * will mention everything from all the 3 tables. You can choose what you want as the result.

How do I select all the dealers that did not have an order?

I am trying to join two tables and only select the dealers that did not have their promo code used on any order.
How can I do this?
I'm trying this below, but it's not working right. In the example I want to get just Bob, since his promo_code hasn't been used in any orders.
SELECT d.`name`
FROM z_dealer d
LEFT OUTER JOIN z_order o ON (d.promo_code = o.promo_code)
AND o.promo_code IS NULL
Here are my tables...
mysql> select * from z_dealer;
+----+------+------------+
| id | name | promo_code |
+----+------+------------+
| 1 | John | holiday |
| 2 | Suzy | special |
| 3 | Bob | laborday |
+----+------+------------+
mysql> Select * from z_order;
+----+-------+------------+
| id | total | promo_code |
+----+-------+------------+
| 1 | 10 | holiday |
| 2 | 20 | special |
| 3 | 15 | holiday |
| 4 | 45 | special |
+----+-------+------------+
SELECT d.`name` FROM z_dealer d LEFT JOIN z_order o ON (d.promo_code = o.promo_code) WHERE o.promo_code IS NULL
Have you tried INNER JOIN? or You can try IN like this :
SELECT d.name
FROM z_dealer d
WHERE d.promo_code not in( SELECT promo_code FROM z_order)
I'm not entirely sure why it's not working in your example code. I've created the same tables locally and when I run the script you provided I get the single 'Bob' answer.
SELECT d.name
FROM z_dealer d
LEFT OUTER JOIN z_order o ON (d.promo_code = o.promo_code)
AND o.promo_code IS NULL
What results are you seeing exactly?

Mysql include column with no rows returned for specific dates

I would like to ask a quick question regarding a mysql query.
I have a table named trans :
+----+---------------------+------+-------+----------+----------+
| ID | Date | User | PCNum | Customer | trans_In |
+----+---------------------+------+-------+----------+----------+
| 8 | 2013-01-23 16:24:10 | test | PC2 | George | 10 |
| 9 | 2013-01-23 16:27:22 | test | PC2 | Nick | 0 |
| 10 | 2013-01-24 16:28:48 | test | PC2 | Ted | 10 |
| 11 | 2013-01-25 16:36:40 | test | PC2 | Danny | 10 |
+----+---------------------+------+-------+----------+----------+
and another named customers :
+----+---------+-----------+
| ID | Name | Surname |
+----+---------+-----------+
| 1 | George | |
| 2 | Nick | |
| 3 | Ted | |
| 4 | Danny | |
| 5 | Alex | |
| 6 | Mike | |
.
.
.
.
+----+---------+-----------+
I want to view the sum of trans_in column for specific customers in a date range BUT ALSO include in the result set, those customers that haven't got any records in the selected date range. Their sum of trans_in could appear as NULL or 0 it doesn't matter...
I have the following query :
SELECT
`Date`,
Customer,
SUM(trans_in) AS 'input'
FROM trans
WHERE Customer IN('George','Nick','Ted','Danny')
AND `Date` >= '2013-01-24'
GROUP BY Customer
ORDER BY input DESC;
But this will only return the sum for 'Ted' and 'Danny' because they only have transactions after the 24th of January...
How can i include all the customers that are inside the WHERE IN (...) function, even those who have no transactions in the selected date range??
I suppose i'll have to join them somehow with the customers table but i cannot figure out how.
Thanks in advance!!
:)
In order to include all records from one table without matching records in another, you have to use a LEFT JOIN.
SELECT
t.`Date`,
c.name,
SUM(t.trans_in) AS 'input'
FROM customers c LEFT JOIN trans t ON (c.name = t.Customer AND t.`Date` >= '2013-01-24')
WHERE c.name IN('George','Nick','Ted','Danny')
GROUP BY c.name
ORDER BY input DESC;
Of course, I would mention that you should be referencing customer by ID, and not by name in your related table. Your current setup leads to information duplication. If the customer changes their name, you now have to update all related records in the trans table instead of just in the customer table.
try this
SELECT
`Date`,
Customer,
SUM(trans_in) AS 'input'
FROM trans
inner join customers
on customers.Name = trans.Customer
WHERE Customer IN('George','Nick','Ted','Danny')
GROUP BY Customer
ORDER BY input DESC;

Third join to get first_Name and Last_Name of account

I have the following query which matches Account_ID's on Accounts table with the AccountID's on project assigned table and displays the accounts assigned to a project:
SELECT proj.ProjectID, A.Project_Title, B.Account_ID, B.Username, B.Access_Type
FROM Project_Assigned proj
INNER JOIN Account B
ON proj.AccountID = B.Account_ID
INNER JOIN Project A
ON proj.ProjectID = A.Project_ID
WHERE proj.ProjectID = 1;
What I want to do now is get the First_Name, Last_Name from Client table and Agency_Employee table and display the information matched against the Account_ID's. Both Client_ID and Employee_ID are foreign keys of Account_ID. How would I add this information into the join above?
I have attempted to add an additional join but I always get a result set match 0 which I know shouldn't be the case.
Client Table:
+-----------+------------+-----------+
| Client_ID | First_Name | Last_Name |
+-----------+------------+-----------+
| 4 | Phil | Jones |
+-----------+------------+-----------+
Employee Table:
+-------------+------------+-----------+
| Employee_ID | First_Name | Last_Name |
+-------------+------------+-----------+
| 2 | John | Smith |
| 5 | Bob | Jones |
| 6 | Fred | Tucker |
+-------------+------------+-----------+
Account Table:
+------------+----------+
| Account_ID | Username |
+------------+----------+
| 1 | Dan |
| 2 | rjm |
| 3 | pw |
| 4 | Philly |
| 5 | bob |
| 6 | fred |
+------------+----------+
Project Assigned Table:
+-----------+-----------+
| ProjectID | AccountID |
+-----------+-----------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
+-----------+-----------+
I'm not sure, but you seem to indicate that for an Account with ID 5, the Client will have ID 5 and the Employee will have ID 5? Slightly odd, and you probably want to read up on normalisation, but shouldn't this work?
SELECT
proj.ProjectID,
Project.Project_Title,
Account.Account_ID, Account.Username,
Client.First_Name AS Client_First_Name, Client.Last_Name AS Client_Last_Name,
Employee.First_Name AS Employee_First_Name, Employee.Last_Name AS Employee_Last_Name
FROM `Project_Assigned` proj
INNER JOIN `Account` ON (proj.AccountID = Account.Account_ID)
INNER JOIN `Project` ON (proj.ProjectID = Project.Project_ID)
LEFT JOIN `Client` ON (Account.Account_ID = Client.Client_ID)
LEFT JOIN `Employee` ON (Account.Account_ID = Employee.Employee_ID)
WHERE proj.ProjectID = 1;
edit
Okay, I've updated my answer.
You'll have two first names and two lastnames, one of each will always be null.
If you only want one contact name, try this:
SELECT
COALESCE(Client.First_Name, Employee.First_Name) FirstName,
COALESCE(Client.Last_Name, Employee.Last_Name) LastName
SELECT c.First_Name, c.Last_Name, e.First_Name, e.Last_Name
FROM client c, employee e, account a
WHERE c.Client_ID = a.Account_ID OR e.Employee_ID = a.Account_ID
OR
SELECT c.First_Name, c.Last_Name
FROM client c, account a
WHERE c.Client_ID = a.Account_ID
UNION
SELECT e.First_Name, e.Last_Name
FROM employee e, account a
WHERE e.Employee_ID = a.Account_ID