How to do mysql join to get result form 3 tables - mysql

I want to get category id and name from company category table which do not exists in company category cross table. For example the company with id 3 has already category 1 and category 2 and i want the sql result to get category 3
I tried following statement but not getting expected result
SELECT `wp_bmg_company_category`.id, `wp_bmg_company_category`.name
FROM `wp_bmg_company_category`
INNER JOIN `wp_bmg_company_category_cross`
ON `wp_bmg_company_category`.id != `wp_bmg_company_category_cross`.categoryid

if I understood correctly you search category which is now unused.
Select all company data with category ID (return only category ID)
Select all data from category where category id NOT IN (use 1. select data)
And if you find the only unused category for each company separately. Use something like this (ADD company_id for search each company separately, to search unused categories):
SELECT *
FROM category ca
WHERE category_id NOT IN
(SELECT category_id
FROM category c1
JOIN category_cross cc ON c1.id = cc.category_id
WHERE company_id = 1)

What you need is an outer join (left or right) that can retrieve all records from a table, regardless whether it is present in the other table. (You may use not in() or not exists() in place of the outer join).
The other technique you need is called Cartesian join, whereby you match all records from one table with all records from another table. In this case, match all records from the companies table with all records in the categories, to get the complete list of company - category combinations. Then subtract from this the list of categories you have.
select co.id, co.name, ca.id, ca.name
from (wp_bmg_company co join wp_bmg_company_category ca) --this creates the Cartesian join
left join wp_bmg_company_category_cross cr on co.id=cr.companyid and ca.id=cr.categoryid
where cr.id is null --only the non-matched pairs should remain

Related

Find the count of categories from a table

I am trying to develop an enquiry management system for an institute.
I have 3 tables in mysql db.
leads_course_category table keeps course categories and has the columns: category_id, category_name, category_created_time, category_deleted.
leads_course_details table stores courses under categories and has the columns: course_id, course_category_id, course_name.
leads_enquiry_details table stores enquiry details and has the columns: enquiry_id, enquiry_name, leads_course_details_course_id, enquiry_deleted
I need to find the number of enquiries for each category.
I tried the following query:
SELECT category_name,COUNT(*) as COUNT
FROM leads_course_category
RIGHT JOIN leads_course_details
on category_id=leads_course_details.course_category_id
RIGHT JOIN `leads_enquiry_details`
on leads_course_details.course_id= leads_enquiry_details.leads_course_details_course_id
WHERE leads_enquiry_details.enquiry_deleted=1
GROUP BY leads_course_category.category_id
This query skips all the categories having null values, but I need to show that as count of zero.
Please help me to resolve this.
The condition enquiry_deleted = 1 must be moved to the ON clause:
select c.category_name, count(ed.enquiry_id) count
from leads_course_category c
left join leads_course_details cd on c.category_id = cd.course_category_id
left join leads_enquiry_details ed on cd.course_id = ed.leads_course_details_course_id and ed.enquiry_deleted = 1
group by c.category_id, c.category_name

select names that is equal to the id of other tables - SQL

I have two tables products and categories. For products I have the ff fields:
id
pname
category_id
date
And for the cateogries id I have:
id
name
So using inner join I am trying to select all the names of categories that are equal to the category_id inside the products table.
Here's my take:
SELECT
c.name
FROM
categories AS c
INNER JOIN products AS p ON c.id = p.category_id
However this one did not work out and it's just sending me an empty array.
Any idea how can I do this? thanks!
If you just want category names, then exists or in is more appropriate than join:
SELECT c.name
FROM categories c
WHERE EXISTS (SELECT 1 FROM products p WHERE c.id = p.category_id);
You will not have to worry about eliminating duplicates, unless two categories have the same name.
This is also much more efficient than using SELECT DISTINCT on your query, especially if products has an index where category_id is the first key.

selecting only those values from the database which are not selected previously

I have a table category, profile and employee_belongs_to, where employee_belongs_to stores profile_id and category_id. The profile table stores all the employees details. category table stores different category like English, math,physics ...
I have selected all the employees from profile table which corresponds to particular category. I have all profile ids and category ids in employee_belongs_to table, so i joined the table and selected only those names from profile table whose profile_id corresponds to particular category_is in employee_belongs_to table. The following is the SQL statement i wrote.
SELECT profile.* FROM profile JOIN employee_belongs_to JOIN category ON
employee_belongs_to.Profile_id=profile.Profile_id AND
employee_belongs_to.Category_id=category.Category_id WHERE
category.Category_id=? "
Now i want to select only those employees whose names are not retrieved by above SQL statement. How can i write the SQL statement?
This will allow you to SELECT all columns from table PROFILE, while not including the specific profile ID's:
SELECT p.*
FROM [PROFILE] p
WHERE p.Profile_ID NOT IN (
SELECT p.Profile_ID
FROM [PROFILE] p
INNER JOIN employee_belongs_to ebt ON p.Profile_id = ebt.Profile_id
INNER JOIN category c ON ebt.Category_id = c.Category_id
WHERE c.Category_id = 15);
Also I would recommend using aliases like I've done for readability (p, ebt, c), and changing your INNER JOIN's like I've done.
When you fire above query you will get array of data. And based on that you should store id values from array. And then you can use NOT IN() feature of mysql. Using that you will be able to fetch remain data.
SELECT * FROM tableName
WHERE tableName.id NOT IN (1,2,3);
It will return data which is not consider id's of 1,2 and 3.
I hope it may help you

Mysql - How to make this work?

I have a mysql table Products.
It contains the Columns "id,product_name,product_seller,price"
I am trying to create a PHP script to Insert/Update data in the table Products using the seller name (product_seller).
The issue
I don't know what mysql query to use in order to get: A list with All the products NO matter if the seller has it or not and if the seller has the products to give me the details (id,product_name,product_seller,price).
EXAMPLE of what i want to get:
1 - apples - seller A - 12
2 - banana - -
3 - oil - -
4 - dvd - seller A - 25
The product_name must be DISTINCT
Thanks in advance!
* Query must be something like "SELECT DISTINCT product_name FROM Products and let me know where Seller A has the product, at what price, what id what product WHERE seller_name = 'seller A'...yet, show me all products, n matter if seller has it"
Seems to be a straight forward subquery to get a unique list of products then an outer join to get the seller info.
SELECT A.ID, A.Product_name, B.product_Seller, B.Price
FROM (SELECT DISTINCT ID, Product_Name FROM products) A
LEFT JOIN Products B
on A.ID = B.ID
and B.product_Seller = 'seller A'
The LEFT JOIN will ensure you return all the products and only seller information related to the items for 'SELLER A'
SQL generally operates best on data SETS. So I first generate a set of unique IDs and products and then LEFT JOIN this to the sellers product data you desire. The left join ensures we keep all the items. The filtering of the seller MUST be on the JOIN itself and not in the where clause. Otherwise the left join in essence becomes an inner as the NULLS generated from the outer join are removed.
SELECT A.ID, A.Product_name, B.product_Seller, B.Price
FROM (SELECT DISTINCT ID, Product_Name FROM products) A
LEFT JOIN Products B
on A.ID = B.ID
WHERE B.product_Seller = 'seller A'
Wouldn't get the desired result. This is because the where clause is applied after the join so the items that are not associated to the seller would be excluded. Since you want those records, you must use a left join and apply the limit on the JOIN so the items not associated to the seller are returned.
When I initially started with SQL I had trouble with this type of logic. It wasn't until I considered data in terms of "SETS" and how those sets related, that how to solve these questions became easier.
try to use the
SELECT * FROM Products_Table ;
this will obtain all the table values

When to use a left outer join?

I don't understand the concept of a left outer join, a right outer join, or indeed why we need to use a join at all! The question I am struggling with and the table I am working from is here: Link
Question 3(b)
Construct a command in SQL to solve the following query, explaining why it had to employ the
(outer) join method. [5 Marks]
“Find the name of each staff member and his/her dependent spouse, if any”
Question 3(c) -
Construct a command in SQL to solve the following query, using (i) the join method, and (ii) the
subquery method. [10 Marks]
“Find the identity name of each staff member who has worked more than 20 hours on the
Computerization Project”
Can anyone please explain this to me simply?
Joins are used to combine two related tables together.
In your example, you can combine the Employee table and the Department table, like so:
SELECT FNAME, LNAME, DNAME
FROM
EMPLOYEE INNER JOIN DEPARTMENT ON EMPLOYEE.DNO=DEPARTMENT.DNUMBER
This would result in a recordset like:
FNAME LNAME DNAME
----- ----- -----
John Smith Research
John Doe Administration
I used an INNER JOIN above. INNER JOINs combine two tables so that only records with matches in both tables are displayed, and they are joined in this case, on the department number (field DNO in Employee, DNUMBER in Department table).
LEFT JOINs allow you to combine two tables when you have records in the first table but might not have records in the second table. For example, let's say you want a list of all the employees, plus any dependents:
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_last, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE INNER JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
The problem here is that if an employee doesn't have a dependent, then their record won't show up at all -- because there's no matching record in the DEPENDENT table.
So, you use a left join which keeps all the data on the "left" (i.e. the first table) and pulls in any matching data on the "right" (the second table):
SELECT EMPLOYEE.FNAME as employee_first, EMPLOYEE.LNAME as employee_last, DEPENDENT.FNAME as dependent_first, DEPENDENT.LNAME as dependent_last
FROM
EMPLOYEE LEFT JOIN DEPENDENT ON EMPLOYEE.SSN=DEPENDENT.ESSN
Now we get all of the employee records. If there is no matching dependent(s) for a given employee, the dependent_first and dependent_last fields will be null.
example (not using your example tables :-)
I have a car rental company.
Table car
id: integer primary key autoincrement
licence_plate: varchar
purchase_date: date
Table customer
id: integer primary key autoincrement
name: varchar
Table rental
id: integer primary key autoincrement
car_id: integer
bike_id: integer
customer_id: integer
rental_date: date
Simple right? I have 10 records for cars because I have 10 cars.
I've been running this business for 10 years, so I've got 1000 customers.
And I rent the cars about 20x per year per cars = 10 years x 10 cars x 20 = 2000 rentals.
If I store everything in one big table I've got 10x1000x2000 = 20 million records.
If I store it in 3 tables I've got 10+1000+2000 = 3010 records.
That's 3 orders of magnitude, so that's why I use 3 tables.
But because I use 3 tables (to save space and time) I have to use joins in order to get the data out again
(at least if I want names and licence plates instead of numbers).
Using inner joins
All rentals for customer 345?
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
WHERE customer.id = 345.
That's an INNER JOIN, because we only want to know about cars linked to rentals linked to customers that actually happened.
Notice that we also have a bike_id, linking to the bike table, which is pretty similar to the car table but different.
How would we get all bike + car rentals for customer 345.
We can try and do this
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id)
INNER JOIN car on (car.id = rental.car_id)
INNER JOIN bike on (bike.id = rental.bike_id)
WHERE customer.id = 345.
But that will give an empty set!!
This is because a rental can either be a bike_rental OR a car_rental, but not both at the same time.
And the non-working inner join query will only give results for all rentals where we rent out both a bike and a car in the same transaction.
We are trying to get and boolean OR relationship using a boolean AND join.
Using outer joins
In order to solve this we need an outer join.
Let's solve it with left join
SELECT * FROM customer
INNER JOIN rental on (rental.customer_id = customer.id) <<-- link always
LEFT JOIN car on (car.id = rental.car_id) <<-- link half of the time
LEFT JOIN bike on (bike.id = rental.bike_id) <<-- link (other) 0.5 of the time.
WHERE customer.id = 345.
Look at it this way. An inner join is an AND and a left join is a OR as in the following pseudocode:
if a=1 AND a=2 then {this is always false, no result}
if a=1 OR a=2 then {this might be true or not}
If you create the tables and run the query you can see the result.
on terminology
A left join is the same as a left outer join.
A join with no extra prefixes is an inner join
There's also a full outer join. In 25 years of programming I've never used that.
Why Left join
Well there's two tables involved. In the example we linked
customer to rental with an inner join, in an inner join both tables must link so there is no difference between the left:customer table and the right:rental table.
The next link was a left join between left:rental and right:car. On the left side all rows must link and the right side they don't have to. This is why it's a left join
You use outer joins when you need all of the results from one of the join tables, whether there is a matching row in the other table or not.
I think Question 3(b) is confusing because its entire premise wrong: you don't have to use an outer join to "solve the query" e.g. consider this (following the style of syntax in the exam paper is probably wise):
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
UNION
SELECT FNAME, LNAME, NULL
FROM EMPLOYEE
EXCEPT
SELECT FNAME, LNAME, DEPENDENT_NAME
FROM EMPLOYEE, DEPENDENT
WHERE SSN = ESSN
AND RELATIONSHIP = 'SPOUSE'
In general:
JOIN joints two tables together.
Use INNER JOIN when you wanna "look up", like look up detailed information of any specific column.
Use OUTER JOIN when you wanna "demonstrate", like list all the info of the 2 tables.