how to select not in relation data using left join - mysql

I know it's ambiguous subject, because if i know what exactly the name, google will give me the answer. And, sorry for the english.
Okay i have 3 tables looks like below
job job_hide user
--- -------- ----
id job_id id
name user_id name
let say we have 3 job with 1, 2, 3 as id and 2 user test1, test2 as id and 1 record for job_hide with 2 as job_id and test2 as user_id.
my question is, how i can use left join in case user test2 logged and i want to select all job except job with id 2 because job with id 2 has been added to job_hide table.
Thanks in advance.

You can simply use an is null condition for that purpose:
select job.* from job left join job_hide
on (job.id = job_hide.job_id and job_hide.user_id = 'test2')
where job_hide.job_id is null

SELECT id, name
FROM job
WHERE id NOT IN
( SELECT job_id
FROM job_hide AS jh
WHERE jh.job_id = job.id
AND jh.user_id = 2 --- 2 is the #id_of_the_logged_user
)

Related

MySQL query is not returning correctly

--Edit
I still dont get it for some reason. I will give more detail about my problem.
jobs table
id, title ... all details
1, title1,...
2, title2,...
3, title3,...
4, title4,...
job_user table
id,id_job,id_user
1,1,1
2,2,3
3,3,3
4,4,4
following_job table
id,id_job,id_user
1, 1, 3
So basically, user 3 has 2 jobs (2,3), and he follows job 1 of user 1. so, if i login as user 3, i would like to get all details jobs of user <> 3 (just the requirement that i need to do).
i would get the result
id,id_job,id_user
1,1,1
4,4,4
My goal results would be :
id,title..., following_id
1,title1,...,1
4,title4,...,0
the following_id will be added as result above, since user 3 followed id_job 1 so its following_id = 1 else = 0. And id_job 1,4 will joined with jobs table to get details about it : title ...
I am doing the follow/unfollow job functionality
Thanks all
Typically you would have a second table which contains the id_job values you want to search/match, something like this:
has_jobs
id_job | (other columns...)
2
3
Then, you could just left join has_jobs to following_job to get the result you want:
SELECT t2.id
t1.id_job,
CASE WHEN t2.id_job IS NULL THEN 0 ELSE 1 END AS following_id
FROM has_jobs t1
LEFT JOIN following_job t2
ON t1.id_job = t2.id_job
If you don't have an actual has_jobs table, then you could use an inline table instead:
SELECT t2.id
t1.id_job,
CASE WHEN t2.id_job IS NULL THEN 0 ELSE 1 END AS following_id
FROM
(
SELECT 2 AS id_job
UNION ALL
SELECT 3
-- add more IDs here if wanted
) t1
LEFT JOIN following_job t2
ON t1.id_job = t2.id_job

Select From table name obtained dynamically from the query

I have 3 Tables
campaign1 (TABLE)
id campaign_details
1 'some detail'
campaign2 (TABLE)
id campaign_details
1 'some other detail'
campaign_list (TABLE)
id campaign_table_name
1 'campaign1'
2 'campaign2'
Campaign list table contains the table name of the two tables described above. I want to Select from the Campaign List table and get the record count using the table name i get from this select
For eg.
using select i get campaign1(Table name). Then i run select query on campaign1 to count number of records.
What i'm doing right now is .
-Select from campign_list
-loop through all campaign_table_names and run select query individually
Is there a way to do this using a single query
something like this
select campaign_name,(SELECT COUNT(*) FROM c.campaign_name) as campcount from campaign_list c
SQLFiddle : http://sqlfiddle.com/#!9/b766d/2
It's not possible inside a single query to build it dynamically but it's possible to cheat. Especially if there are only two linked tables.
I've listed two options
left outer join both tables
select campaign_name,
coalesce(c1.campaign_details, c2.campaign_details)
from campaign_list c
left join campaign1 c1 using (id)
left join campaign2 c2 using (id);
union all two different selects
select campaign_name,
campaign_details
from campaign_list c
join campaign1 c1 using (id)
union all
select campaign_name,
campaign_details
from campaign_list c
join campaign2 c2 using (id);
sqlfiddle
Combine your campaign tables to 1 table and add an column named 'type' (int).
campaign_items tables:
item_id item_details item_type
1 'some detail' 1
2 'some detail' 1
3 'some other detail' 2
4 'some other detail' 2
campaign_lists table
campaign_id campaign_name
1 'campaign1'
2 'campaign2'
Then you can use the following select statement:
SELECT campaign_name, (SELECT COUNT(*) FROM campaign_items WHERE item_type = campaign_id) as campaign_count
FROM campaign_lists
Oops, writing took me so long that you got this answered by Colin Raaijmakers already. Well, I'll post my answer anyway in spite of being more or less the same answer. Maybe my elaboration helps you see the problem.
Your problem stems from a bad database design. A database is made to order data and its relations. A CD database holds albums, songs, artists, etc. A business database may hold items, warehouses, sales and so on. Your database holds table names. [... time for thinking :-) ]
(When writing a DBMS you would want to store table names, column names, constraints etc., but I guess I am right supposing that you are not writing a new DBMS.)
So create tables that deal with your actual data. E.g.:
campain_type (id_campain_type, description, ...)
campain (id_campain, id_campain_type, campain_date, ...)
campain_type
id_campain_type description
1 Type A
2 Type B
3 Type C
campain
id_campain id_campain_type date
33 1 2015-06-03
85 2 2015-10-23
97 2 2015-12-01
query
select
ct.description,
(select count(*) from campain c where c.id_campain_type = ct.id_campain_type) as cnt
from campain_type ct;
result
description cnt
Type A 1
Type B 2
Type C 0

Select rows based on values from two tables

I got the following tables in my mysql database: http://i.gyazo.com/8da933221a20ecb0e8f4a8073a2a5b41.png
table: ACCOUNTS
ID NAMN
-- -----
1 Name1
2 Name2
3 Name3
4 Name4
table: SUBBED
SUBSCRIBER RECEIVER
---------- --------
1 4
1 3
I would like to select ID, NAME from ACCOUNTS where account X (lets say the one with ID 1) isn't subscribed to.
If you look at the image, you can see that the account with NAME = Name1 is subscribed to Name3 and Name4. In this case, the query should return the second row from ACCOUNTS where ID = 2.
Does someone know what the query might look like?
You probably just want to left join the tables together, and then find the ones that don't match. Something like this:
select a1.*
from accounts a1
left join subbed s1
on a1.id = s1.receiver
and s1.subscriber = 1
where s1.subscriber is null and a1.id <> 1;
demo here
You can try something like this.
SELECT ID, NAME FROM ACCOUNTS WHERE ID NOT IN (SELECT RECEIVER FROM SUBBED)
Hope it helps.
Select ID, NAME
From ACCOUNTS
Where ID Not In (Select RECEIVER
From SUBBED
Where SUBSCRIBER = (Your X))

Mysql show different columns for different where clauses

I want to show a output table that counts all the users found in a table.
Basically I want the output to look like:
+-----------+-----------+
| user1 | user2 |
+-----------+-----------+
| 5 | 2 |
+-----------+-----------+
I'm just using a dummy table to test this. My query looks like this:
(
select
name as user1
from
users
where
name = 'root'
) UNION (
select
name as user2
from
users
where
name = 'not_root'
)
Which only outputs something like this:
+-----------+
| user1 |
+-----------+
| 5 |
| 2 |
+-----------+
EDITED
The main idea of the approach it's treat a table as two different virtual tables in subquery. We can make nested select statement e.g. (select count(*) as c from users where name = 'root') u1 MySql treats it as particular table named u1 with one row and one column named c.
select u1.c as root_cnt, u2.c as not_root_cnt
from (select count(*) as c from users where name = 'root') u1,
(select count(*) as c from users where name = 'not_root') u2
or
Moreover if you have select statement that returns only one row you can put nested selects directly in fields list
select (select count(*) as c from users where name = 'root') as root_cnt, (select count(*) as c from users where name = 'not_root') as not_root_cnt
Definite disadvantage of such approach it's extra subqueries. Method based on using case when construction free from such disadvantage.
Try this
SELECT
SUM(CASE WHEN Name = 'root' THEN 1 ELSE 0 END) user1,
SUM(CASE WHEN Name = 'not_root' THEN 1 ELSE 0 END) user2
FROM Users
You can use a case statement inside of count to get the counts in separate columns
select
count(case when name = 'root' then 1 end) user1,
count(case when name = 'not_root' then 1 end) user2
from users
where name in ('root','not_root')
It seems your query is wrong..
union won't combine the results of two queries in the way you have described above.
union would combine the result of two or more select statements but wouldn't "join" it.
You might want to use joins for this cause. still you wouldn't be able to put 5|2 in same row as it basically suggests --> fetch user 1 and user 2 values for one particular type
i think group by is a much better approach:
select user, count(user) from users group by user

Select unique ids from multi values on one column in another table

I'm stuck for hours on an issue that might be pretty simple to solve but I'm just so lost...
I got 3 tables :
user
id name
----------
1 jack
2 john
...
car
id name
----------
1 ford
2 fiat
3 alfa
4 lada
...
user_car
id_user id_car
-----------------
1 2
1 4
2 1
2 2
2 3
For example, i want to get all users with cars which have id 1 AND 2 in the user_car table so I should get the id_user 2 only and I can't find the proper way to do it.
try this untested query:
select * from user join user_car car1 on id =car1.user_id
join user_car car2 on id =car2.user_id where car1.id_car=1 and car2.id_car=2
I would use UNION for this matter:
SELECT id as id_user from user where id in(1, 2)
UNION
SELECT id as id_car from car where id in (1, 2)
You can use COUNT to do this:-
SELECT user.name
FROM user
INNER JOIN user_car ON user.id = user_car.id_user
INNER JOIN car ON user_car.id_car = car.id
WHERE car.id IN (1,2)
GROUP BY user.name
HAVING COUNT(DISTINCT car.id) = 2
Note that this could be simplified to remove the need for the car table when you are just using the id of the car.
May be you want this
SELECT *
FROM USER
WHERE id IN
(SELECT id_user
FROM user_car
WHERE id_car=1 OR id_car=2);