MySQL Join statement - sql

I know how to get a single record from multiple tables using Join. How do you get multiple records?
E.G
Table: categories
id
name
description
Table: some_table
id
name
content
category_id
How would I extend the basic query below to pull all records from within all categories?
SELECT c.id, c.name as category_name FROM categories AS c

The exact join depends on your needs, but the following will show all data from category and some_table where there is at least one row in some_table that matches the value in category. Empty categories will not be shown; you can use a LEFT JOIN instead if you want to show empty category records with NULL values for the records that would otherwise come from the some_table table.
SELECT *
FROM categories c
INNER JOIN some_table st ON (c.id = st.category_id);

Related

SQL Join between two tables excluding some fields

I have two tables Customer and Beneficiary, the relation between them is ManyToMany,
the generated table customers_beneficiaries contains the Id of Beneficiary and the Id of Customer
i want to get the list of customers with a given beneficiary_id
SELECT * from customer c
Full OUTER JOIN customers_beneficiaries cb
ON c.id= cb.customer_id
WHERE cb.beneficiary_id=8;
But the result iam getting contains the two fields of customers_beneficiaries table (customer_id && beneficiary_id)
How can i exclude them from the result
Thank you .
Try this:(In case you can change id column name in customer table to customer_id)
SELECT c.* from customer c
Full OUTER JOIN customers_beneficiaries cb
USING(customer_id)
WHERE cb.beneficiary_id=8;
USING Clause is like ON Clause which takes list of columns on which joining of table has to be done but those columns have to exist in both tables. The columns used in join operation appears only once in output.

SQLite select query if inner join query doesn't exists

I have two tables, one for all the foods which contains food id, default name and other foods values.
Another table is for the food name translations which contains food id, language id, translation.
What i want to do is join between these tables by the food id to get the translation for food id = 5 for example and language id = 1 which is Spanish for example. and i do it by:
SELECT *
FROM Foods
INNER JOIN FoodNameTranslations USING(Food_ID)
WHERE Food_ID = 5
AND Language_ID = 1
Now what if the the 'FoodNameTranslations' table doesn't have a translation for Food_ID 5 and Language 1?
then i want to simply get the food row with food id = 5 from the 'Foods' table (that contains the default name).
How can i make one query that does this? thanks!
You would do a LEFT JOIN and put the language ID into the join condition.
SELECT
COALESCE(t.TranslatedName, f.DefaultName) FoodName
FROM
Foods f
LEFT JOIN FoodNameTranslations t ON t.Food_ID = f.Food_ID AND t.Language_ID = 1
WHERE
f.Food_ID = 5
You cando do this by changing the JOIN condition:
INNER JOIN gets all records that are common between both tables based on the supplied ON clause.
LEFT JOIN gets all records from the LEFT linked and the related record from the right table ,but if you have selected some columns from the RIGHT table, if there is no related records, these columns will contain NULL.
RIGHT JOIN is like the above but gets all records in the RIGHT table.
FULL JOIN gets all records from both tables and puts NULL in the columns where related records do not exist in the opposite table.
Try using LEFT JOIN instead INNER JOIN, you query will be like this:
SELECT *
FROM Foods
LEFT JOIN FoodNameTranslations USING(Food_ID)
WHERE Food_ID = 5
AND Language_ID = 1

SQL many-to-many, how to check criteria on multiple rows

In many-to-many table, how to find ID where all criteria are matched, but maybe one row matches one criterion and another row matches another criterion?
For example, let's say I have a table that maps shopping carts to products, and another table where the products are defined.
How can I find a shopping cart that has at least one one match for every criterion?
Criteria could be, for example, product.category like '%fruit%', product.category like '%vegetable%', etc.
Ultimately I want to get back a shopping cart ID (could be all of them, but in my specific case I am happy to get any matching ID) that has at least one of each match in it.
I am assuming a table named cart_per_product with fields cart,product, and a table named product with fields product,category.
select cart from cart_per_product c
where exists
(
select 1 from product p1 where p1.product=c.product and p1.category like N'%fruit%'
)
and exists
(
select 1 from product p2 where p2.product=c.product and p2.category like N'%vegetable%'
)
You can use ANY and ALL operators combined with outer joins. A simple sample on a M:N relation:
select p.name
from products p
where id_product = ALL -- all operator
( select pc.id_product
from categories c
left outer join product_category pc on pc.id_product = p.id_product and
pc.id_category = c.id_category
)
I think you can figure out the column names
select c.id
from cart c
join product p
on c.pID = p.ID
group by c.id
having count(distinct p.catID) = (select count(distinct p.catID) from product)
Generic approach that possibly isn't the most efficient:
with data as (
select *,
count(case when <match condition> then 1 end)
over (partition by cartid) as matches
from <cart inner join products ...>
)
select * from data
where matches > 0;

sql server - how to modify values in a query statement?

I have a statement like this:
select lastname,firstname,email,floorid
from employee
where locationid=1
and (statusid=1 or statusid=3)
order by floorid,lastname,firstname,email
The problem is the column floorid. The result of this query is showing the id of the floors.
There is this table called floor (has like 30 rows), which has columns id and floornumber. The floorid (in above statement) values match the id of the table floor.
I want the above query to switch the floorid values into the associated values of the floornumber column in the floor table.
Can anyone show me how to do this please?
I am using Microsoft sql server 2008 r2.
I am new to sql and I need a clear and understandable method if possible.
select lastname,
firstname,
email,
floor.floornumber
from employee
inner join floor on floor.id = employee.floorid
where locationid = 1
and (statusid = 1 or statusid = 3)
order by floorid, lastname, firstname, email
You have to do a simple join where you check, if the floorid matches the id of your floor table. Then you use the floornumber of the table floor.
select a.lastname,a.firstname,a.email,b.floornumber
from employee a
join floor b on a.floorid = b.id
where a.locationid=1 and (a.statusid=1 or a.statusid=3)
order by a.floorid,a.lastname,a.firstname,a.email
You need to use a join.
This will join the two tables on a certain field.
This way you can SELECTcolumns from more than one table at the time.
When you join two tables you have to specify on which column you want to join them.
In your example, you'd have to do this:
from employee join floor on employee.floorid = floor.id
Since you are new to SQL you must know a few things. With the other enaswers you have on this question, people use aliases instead of repeating the table name.
from employee a join floor b
means that from now on the table employee will be known as a and the table floor as b. This is really usefull when you have a lot of joins to do.
Now let's say both table have a column name. In your select you have to say from which table you want to pick the column name. If you only write this
SELECT name from Employee a join floor b on a.id = b.id
the compiler won't understand from which table you want to get the column name. You would have to specify it like this :
SELECT Employee.name from Employee a join floor b on a.id = b.id or if you prefer with aliases :
SELECT a.name from Employee a join floor b on a.id = b.id
Finally there are many type of joins.
Inner join ( what you are using because simply typing Join will refer to an inner join.
Left outer join
Right outer join
Self join
...
To should refer to this article about joins to know how to use them correctly.
Hope this helps.

Sql distinct selective row after a join question

Let's say i have 2 tables Customer and Books.
Table Books can have multiple rows that pertain to a row in Customer.
Ex:
customer John Doe has an id of 1000.
Table Books has 2 rows with a member_id column with 1000 (John Doe).
These 2 rows are identical EXCEPT one of the fields (book title) is empty. The other row has a value for a title.
Question:
How can i query this so that I retrieve the row with the valid title value, BUT, if both title values are empty, then it just returns a single row?
I certainly hope that made sense.
You should be able to use a distinct operator:
SELECT DISTINCT Customers.member_id, Books.book_title
FROM Customers
INNER JOIN Books ON Customers.member_id = Books.member_id
If that does not work correctly you could use an inner select:
SELECT DISTINCT *
FROM (SELECT Customers.member_id, Books.book_title
FROM Customers
INNER JOIN Books ON Customers.member_id = Books.member_id) As newTable
Also, if this is a frequently used query I would avoid a UNION because they are known to have performance problems.
In response to the edit:
SELECT Customers.member_id, Customer_Info.Name, ISNULL(newTable.book_title, '')
FROM Customers
INNER JOIN Customer_Info
LEFT JOIN (SELECT DISTINCT member_id, book_title FROM Books) newTable
ON newTable.member_ID = Customers.member_id
This should return all books associated with a customer (but only one time for each title and if no books are found then it will return an empty string.) If this does not answer the question please include some additional information about the tables and an example of the result you would like and I will update.
OK, now I think I know what you are looking for:
Here is a possible query based on your original question using the tables provided. However, it will not work if the customer has two distinct e-mail addresses set; in that case, you could add a TOP(1) to ensure only one result but you won't know if it is the "right result."
SELECT Customers.member_id, Office.Office_Name, ISNULL(newTable.email, '')
FROM Customers
INNER JOIN Office
LEFT JOIN (SELECT DISTINCT member_id, email
FROM Books
WHERE email IS NOT NULL AND email <> '') newTable
ON newTable.member_ID = Customers.member_id
Here is another query based on the data you provided and the example output.
SELECT Member_Name, Email
FROM thridTable
WHERE Member_Name = #SomeInputParameter
I'm not sure how representative your sample data is but why would you be storing the member name in more than one table? That is a guaranteed headache in the future.
If I understand what you're saying, this query will return all records with a non-null book title plus all customer records that have no valid book records, valid being defined as a book record with a non-null title.
SELECT c.id, c.name, b.title
FROM customer c
JOIN book b ON c.id = b.customer_id
WHERE b.title IS NOT NULL
UNION ALL
SELECT c.id, c.name, NULL
FROM customer c
WHERE NOT EXISTS (SELECT title FROM book b WHERE customer_id = c.id AND title IS NOT NULL)
You can use:
isnull(BOOKTITLE,'') = ''
on that field and a distinct, and it should give one result