I have a mysql table with the following structure:
id_category | id_product
1 1
15 1
28 1
5 2
15 2
1 2
13 3
4 3
I would like to make a query that I will use inside an "AND" clause of a JOIN structure which selects the products that have e.g. the id_category 1 and 15 and the output to be the id of the product but only once:
id_product
1
2
You may do as
select
id_product from table_name
where id_category in (1,15)
group by id_product
having count(*) = 2
You can use this:
select distinct(id_product) from TABLENAME
where id_category in (1,15)
You can use like this ;
select distinct(id_product) from table_name
where id_category=1 or id_category=15
group by id_product;
Here is SqlFiddle example
EDIT:
I understand what you mean.. I can give two example using join and where clause;
Lets look at first example;
SELECT `settings`.*, `character_settings`.`value`
FROM (`settings`)
LEFT JOIN `character_settings`
ON `character_settings`.`setting_id` = `settings`.`id`
WHERE `character_settings`.`character_id` = '1'
As you see in the first example, character_id is filtering with where clause however, The where clause is filtering away rows where the left join doesn't succeed. So we need to do this in join with AND Move it to the join:
SELECT `settings`.*, `character_settings`.`value`
FROM `settings`
LEFT JOIN
`character_settings`
ON `character_settings`.`setting_id` = `settings`.`id`
AND `character_settings`.`character_id` = '1'
So in order to use WHERE clause in join, use AND operator in JOIN. Hope this is helpful to solve your question.
EDIT2 :
In your problem it possible that you need to use OR not AND
Related
I have a table which has certain IDs, and values against them. If I pass a list of IDs in the where clause it will return only matching IDs, and discard the rest. How can I get the unmatched IDs also with a null value against them.
Table:
select * from members;
Result:
|member_id |price |
+--------------+-------
| 0 |1234 |
| 1 |99 |
+--------------+-------
However if we run this query, it won't return the unmatched values.
select member_id,price from members where member_id in (0,1,2,3)
How can I show IDs 2&3 as well, but with a null against them for price column?
Thanks!
The values can't appear exclusively in the where clause; they must appear somehow in the from clause. You must create a view of some sort including those values. A common way is to use an Oracle-provided collection type and select from it, something like this:
select t.column_value as member_id, m.price
from sys.odcinumberlist(0, 1, 2, 3) t left outer join members m
on t.column_value = m.member_id
;
MEMBER_ID PRICE
---------- ----------
0 1234
1 99
2
3
odcinumberlist is a collection data type (varray of number) defined in the sys package, provided by Oracle. When used in the from clause of a select statement, the values are in a column named column_value.
Whether this will work in "mariadb" (whatever that is), you will have to try and see. If it does not, you can try something more traditional, like
select t.member_id, m.price
from (
select 0 as member_id from dual union all
select 1 from dual union all
select 2 from dual union all
select 3 from dual
) t
left outer join members m on t.member_id = m.member_id
;
You can use a LEFT JOIN for this:
SELECT m.member_id, m.price
FROM members m
LEFT JOIN members m2 ON m2.member_id = m.member_id
AND m2.member_id IN (0,1,2,3)
WHERE m2.member_id IS NULL
PEOPLE PEOPLE_FAVS
id user_id fav_id
------ ------- ----------
1 1 1
2 1 2
3 1 5
4 2 1
5 2 2
6
I have two tables PEOPLE and PEOPLE_FAVS, I am trying to get all PEOPLE which have not favorited number '5' so it should return
PEOPLE
id
------
2
3
4
5
6
I'm trying with this query:
SELECT `people`.`id`
FROM `people`
LEFT OUTER JOIN `people_favs` ON (`people_favs`.`user_id` = `people`.`id`)
WHERE (`people_favs`.`fav_id` != 5)
GROUP BY `people`.`id`
Here is a SQL Fiddle: http://sqlfiddle.com/#!2/4102b8/3
SELECT p.*
FROM people p
LEFT
JOIN people_favs pf
ON pf.user_id = p.id
AND pf.fav_id = 5
WHERE pf.fav_id IS NULL
http://sqlfiddle.com/#!2/665b6/1
You don't actually need to use an outer join. Outer joins are often used when you want to see ALL rows from one table, regardless of their condition with another. While it would work in this case (as seen by Strawberry's example), you can use the NOT EXISTS operator to check for ids that do not have 5 as a favorite.
As far as I am aware, there is little to no performance difference, but this query is a little shorter. I also feel it is a little more logical, because you aren't really joining information. That's just a personal opinion/thought though.
Try this:
SELECT id
FROM people
WHERE NOT EXISTS(SELECT id FROM people_favs WHERE fav_id = 5 AND user_id = id);
SQLFiddle example using your data.
Did you try to simply do this:
SELECT DISTINCT `people`.`id`
FROM `people`
JOIN `people_favs` ON (`people_favs`.`user_id` = `people`.`id`)
WHERE (`people_favs`.`fav_id` <> 5)
GROUP BY `people`.`id`
I have two tables in my MySQL database:
table_bookings:
id - bookings
1 - 1
2 - 1,2,3
3 - 2,3
table_services:
id - name
1 - Facial
2 - Corporal
3 - Others
I need to make a query to get the following result:
id - services_id - services_name
1 - 1 - Facial
2 - 1,2,3 - Facial, Corporal, Others
3 - 2,3 - Corporal, Others
First Change your table layout to something like this:
table_bookings:
id | booking
1 | 1
2 | 1
2 | 2
2 | 3
3 | 2
3 | 2
After that you can join this table by booking-id to the Translation:
SELECT * FROM table_bookings AS a JOIN table_services AS b ON a.booking = b.id
If you Play around with GROUP_CONCAT after that you should get your desired result.
It looks like you need to join table table_bookings to table table_services to combine information from both tables in the result.
To join the two tables, you need to join them on a matching column. In other words, there needs to be a column in both tables which essentially represents the same thing -- then you can join using this column.
It looks like column bookings in table_bookings corresponds to id in table_services so you should join on these columns.
Consider normalize data. This can be done with these queries from existing data:
CREATE TABLE booking_services AS
SELECT DISTINCT b.id AS booking_id, s.id AS service_id
FROM table_bookings b
INNER JOIN table_services s ON FIND_IN_SET(s.id, b.bookings) > 0;
ALTER TABLE booking_services
ADD PRIMARY KEY (booking_id, service_id);
After normalization your query can be this:
SELECT
bs.booking_id,
GROUP_CONCAT(bs.service_id ORDER BY bs.service_id) AS services_id,
GROUP_CONCAT(s.name ORDER BY bs.service_id SEPARATOR ', ') AS services_name
FROM
booking_services bs
INNER JOIN
table_services s ON s.id = bs.service_id
GROUP BY bs.booking_id
Yes, you can write query on non normalized data:
SELECT
b.id,
b.bookings AS services_id,
GROUP_CONCAT(s.name ORDER BY s.id SEPARATOR ', ') AS services_name
FROM
table_bookings b
INNER JOIN
table_services s ON FIND_IN_SET(s.id, b.bookings) > 0
GROUP BY b.id, b.bookings
But on large data sets query on normalized data performs faster - see execution plans (See EXPLAIN syntax).
Test both queries on SQL Fiddle
Documentation:
Database normalization
CREATE TABLE ... SELECT Syntax
ALTER TABLE Syntax
FIND_IN_SET(str,strlist)
GROUP_CONCAT(expr)
I have query that LEFT joins information from two tables. With code with following joins
LEFT JOIN A on source = news_id
LEFT JOIN B on source = other_news_id
How can join or display data from the two columns so it produces one column information.
ID source Left Join on ID a Left Join on ID b
a 1 info1 <null>
a 2 info2 <null>
b 3 <null> info3
b 4 <null> info4
Something along the lines of
ID source info
a 1 info1
a 2 info2
b 3 info3
b 4 info4
How can I bring all left joins into one column?
You can use COALESCE() if there will always only be one value. It returns the first non-null argument.
SELECT ID, source, COALESCE(infoa, infob) AS info FROM ...
The COALESCE function will do this.
See the MySQL documentation for examples of how to use this function.
From the sample data, it seems that no A.news_id is never equal to a B.other_news_id and the two columns you want to COALESCE have at least one NULL value.
I also guess your FROM clause is something like this:
FROM T
LEFT JOIN A on T.source = A.news_id
LEFT JOIN B on T.source = B.other_news_id
If that's the case, you could also rewrite the query with a UNION:
SELECT ID, source, infoa AS info
FROM T
JOIN A on T.source = A.news_id
WHERE ...
UNION ALL
SELECT ID, source, infob
FROM T
JOIN B on T.source = B.other_news_id
WHERE ...
If I understand you correctly, you need to use INNER JOINs instead of LEFT JOINs
I have 2 tables as below:
1.Products
product_id, name
1 Books A
2 Books B
3 Books C
4 Books D
5 Books E
2.liked_items
user_id, product_id
1 4
1 3
1 1
I want to query (sql) to retrieve result as below.
Can I do in same single query?
product_id, user_id
1 1
2 0
3 1
4 1
5 0
Hi, this first time i'm posting here.
Hope anyone can help me. Thank you
SELECT Products.product_id,liked_items.product_id,liked_items.user_id
FROM Products
LEFT JOIN liked_items
ON Products.product_id=liked_items.product_id
Try this one,
SELECT a.product_ID,
COALESCE(b.user_id,0) `user_id`
FROM products a
LEFT JOIN liked_items b
ON a.product_ID = b.product_ID
Sometimes liked_items.user_id can be possibly NULL so instead of displaying NULL in the result list, it can be changed using COALESCE. COALESCE is a function that can change NULL value into your desired value.
Click For Demonstration
SELECT
Products.product_id AS product_id,
IFNULL(liked_items.user_id,0) AS user_id
FROM Products
LEFT JOIN liked_items ON liked_items.product_id=Products.product_id
If you're using MS SQL Server you can use IsNull like so:
SELECT p.product_id, IsNull(li.user_id, 0)
FROM products p
LEFT JOIN liked_items li
ON (p.product_id = li.product_id);
If not, Joao or John's answer will do just fine.