to get different columns from single query - mysql

Consider the data about projects and members stored in tables below.

Projects(id, title)
Members(id, name, project_id)

Generate a report to list all the projects, members working on them. Also list the projects that do not have any employees assigned yet and also the employees who are available as free resources.
Table-
Projects(id, title)
Members(id, name, project_id)
can someone optimize the query as i applied outer join and i got all answers together.i need to separate the columns as per required question.
Select p.title, m.id
From projects p FULL OUTER JOIN
Members m
where p.id = m.project_id;

MySQL does not support full join. So do this in two steps:
Select p.title, m.id
From projects p LEFT JOIN
Members m
ON p.id = m.project_id
union all
select null, m.id
from members m
where not exists (select 1 from projects p where p.id = m.project_id);

Related

Using two inner join tables

I have come up with two queries, both use an inner join on two different tables.
Query 1
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL, CATEGORIES.NAME AS CATEGORY
FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY = CATEGORIES.ID;
Query 2
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT, PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY, PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID;
Both queries run fine on their own, when I try to use both inner joins together I get errors. This is what I came up with on my own. I'm having trouble understanding the syntax to achieve this.
SELECT PRODUCTS.CODE, PRODUCTS.REFERENCE, PRODUCTS.TAXCAT,
PRODUCTS.DISPLAY,PRODUCTS.NAME, PRODUCTS.PRICEBUY,
PRODUCTS.PRICESELL,STOCKCURRENT.UNITS AS UNIT FROM PRODUCTS INNER JOIN
STOCKCURRENT ON STOCKCURRENT.PRODUCT = PRODUCTS.ID, CATEGORIES.NAME AS
CATEGORY FROM PRODUCTS INNER JOIN CATEGORIES ON PRODUCTS.CATEGORY =
CATEGORIES.ID;
Thank you.
Your attempted query has several syntax problems. Assuming you just want to join together the three tables, you may try the following query:
SELECT
p.CODE,
p.REFERENCE,
p.TAXCAT,
p.DISPLAY,
p.NAME,
p.PRICEBUY,
p.PRICESELL,
s.UNITS AS UNIT,
c.NAME AS CATEGORY
FROM PRODUCTS p
INNER JOIN STOCKCURRENT s
ON s.PRODUCT = p.ID
INNER JOIN CATEGORIES c
ON p.CATEGORY = c.ID;
Note that I introduced table aliases here. These aliases can be used elsewhere in the query to avoid having to repeat the entire table name.
By the way, I can also see taking a union of your two original queries. But without expected output, it was not entirely clear what you want.

MySQL JOIN tables with COUNT values

I have the following tables in my database.I only listed the important columns which can be used for joining.
I need to get the following output
Currently I'm using two seperate queries for each COUNT value
For assigned licenses
select
products.id,products.name,COUNT(assigned_licenses.id)
from
deployment_users
inner join
assigned_licenses
on
deployment_users.id = assigned_licenses.deployment_user_id
inner join
products
on
assigned_licenses.id = products.id
and
deployment_users.customer_id = 10
group by
assigned_licenses.id
;
For total licenses
select
products.id,products.name,COUNT(total_licenses.id)
from
customers
inner join
total_licenses
on
customers.iccode = licenses.iccode
inner join
products
on
total_licenses.id = products.id
and
customers.id = 10
group by
total_licenses.id
;
Since there are more than a 1,000 products that need to be listed,I want to combine them into a single query.How can I do that?
Your specification leaves some room for interpretation (e.g. can a user have assigned licenses without total licenses? if yes my query will fail.) but I would go with this.
SELECT
products.id,
products.name,
Count(Distinct total_licenses.id) As CountTotalLicenses,
Count(Distinct assigned_liceses.deployment_users_id) As CountAssignedLicenses
FROM products
LEFT JOIN total_licenses ON total_licenses.products_id = products.id
LEFT JOIN customers ON customers.iccode = total_licenses.customers_iccode
LEFT JOIN assigned_licenses ON assigned_liceses.total_licenses_id = total_licenses.id
WHERE
customers.id = 10
GROUP BY
products.id,
products.name
For the future it would be awesome if you could paste code as code and not as an image. People cannot simple copy paste snippets of your code and have to type everything again...
Try joining Both of your query
SELECT * FROM (
(First Query) as assigned_licn
INNER JOIN
(Second Query) as total_licn
USING (id)
);

SQL Nested Inner Joins

Im trying to use the results of an inner join in another query and having trouble getting my head around how.
This is the first query i am running:
SELECT projects.Project_ID, projects.Name
FROM projects
INNER JOIN assigned_users
ON assigned_users.Project_ID=projects.Project_ID AND assigned_users.User_ID=4;
This is getting all of the assigned projects for a particular user. The Project_ID's this query returns i want to use to find all the related requirements for those projects.
SELECT *
FROM requirements
WHERE requirements.Project_ID=1;
So instead of finding the requirements for project '1' i want to get the requirements for all projects assigned to a particular user. Any help would be appreciated.
Cheers
If I understand correctly, you would just add another JOIN:
SELECT . . .
FROM assigned_users au JOIN
projects p
ON au.Project_ID = p.Project_ID JOIN
requirements r
ON r.Project_ID = p.Project_ID
WHERE au.User_ID = 4;
To the existing query, we can just add:
JOIN requirements
ON requirements.Project_ID = projects.Project_ID
We add expressions to the SELECT list to retrieve values of columns from requirements.
SELECT projects.Project_ID, projects.Name
, requirements.some_column
, requirements.some_other_column
It's likely that we also want to add an ORDER BY clause so that the rows are returned in a predictable sequence.
Note that if there are no matching rows in requirements for a given Project_ID, then that project will not be returned. To return those rows, we can specify an outer join.
Current query:
SELECT projects.Project_ID
, projects.Name
FROM projects
JOIN assigned_users
ON assigned_users.Project_ID=projects.Project_ID
AND assigned_users.User_ID=4
Proposed query with outer join to requirements table:
SELECT projects.Project_ID
, projects.Name
, requirements.Requirement_ID
, requirements.Requirement_Name
FROM projects
JOIN assigned_users
ON assigned_users.Project_ID=projects.Project_ID
AND assigned_users.User_ID=4
LEFT
JOIN requirements
ON requirements.Project_ID = projects.Project_ID
ORDER
BY projects.Project_ID
, requirements.Requirement_ID
Equivalently, we could relocate the condition assigned_users.User_ID=4 from the ON clause of the inner join to a WHERE clause, before the ORDER BY.
You can use either:
SELECT *
FROM requirements req
INNER JOIN projects pro
ON req.Project_ID = pro.Project_ID
INNER JOIN assigned_users u
ON u.Project_ID=pro.Project_ID
WHERE u.User_ID=4;
or
SELECT *
FROM requirements
WHERE requirements.Project_ID=(
SELECT Project_ID
FROM projects
INNER JOIN assigned_users
ON assigned_users.Project_ID=projects.Project_ID AND assigned_users.User_ID=4;
);

SQL Join involving 3 tables, how to?

SQL newbie here.
So we have 3 tables:
categories(cat_id,name);
products(prod_id,name);
relationships(prod_id,cat_id);
It is a one-to-many relationship.
So, given a category name say "Books". How do I find all the products that come under books?
As an example,
categories(1,Books);
categories(2,Phones);
products(302,Sherlock Holmes);
relationships(302,1);
You need to JOIN the three tables.
SELECT p.*
FROM relationships r
INNER JOIN products p
ON p.prod_id = r.prod_id
INNER JOIN categories c
ON c.cat_d = r.cat_id
WHERE c.name = 'Books'
You have to join tables on related columns and specify WHERE clause to select all records where category name = 'Books'
SELECT p.*
FROM categories c
JOIN relationships r ON c.cat_id = r.cat_id
JOIN products p ON r.prod_id = p.prod_id
WHERE c.name = 'Books' -- or specify parameter like #Books
In SQL you often join related tables and beginners tend to join, whatever the situation. I would not recommend this. In your case you want to select products. If you only want to show products data, select from products only. You want to select products that are in the category 'Books' (or for which exists an entry in category 'Books'). Hence use an IN or EXISTS clause in order to find them:
select * from products
where prod_id in
(
select prod_id
from relationships
where cat_id = (select cat_id from categories where name = 'Books')
);
Thus you get a well structured query that tells the reader easily how the tables are related and what data you are actually interested in. Later, with different tables and data to select, this may keep you from duplicate result rows that you must get rid of by using DISTINCT or from getting wrong aggregates (sums, counts, etc.), because of mistakenly considering records multifold.
try this:
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id
where r.cat_id = (select cat_id from categories where name = 'books')
or
select p.Prod_id,p.name
from products p inner join relationships r on
p.prod_id = r.prod_id inner join categories c on c.cat_id = r.cat_id
where c.name = 'books'

How do I perform a simple join on multiple tables?

I have what I'm sure is quite a remedial question here, but I can't for the life of me get this simple join to work.
Basically, I have 3 tables:
MEMBERS (first_name,last_name),
MEMBER_TO_GROUP(member_id,group_id)
PAYMENTS (member_id, date, amount).
I'm looking to grab all payments from members in a specific group. By using only two of the tables, I can find all PAYMENTS of a specific group, without MEMBER information, or I can find all MEMBER information without PAYMENT information. However, when I attempt to add the third table, bad data is returned (e.g. I get members not in the group). This is the basic query i'm using:
SELECT
p.*,
m.first_name,
m.last_name
FROM
members m,
payments p,
member_to_group mg
WHERE
mg.group_id = 12
AND mg.member_id = p.member_id
AND m.member_id = p.member_id
I'm not sure where the disconnect is, but any assistance would be most appreciated.
I think this should get what you want:
SELECT p.*,
m.first_name,
m.last_name
FROM payments p
INNER JOIN members m
ON m.member_id = p.member_id
INNER JOIN member_to_group mg
ON mg.member_id = m.member_id
WHERE mg.group_id = 12