I have a MySQL database with a 1 to N relation in there.
Sample Data:
Table User:
ID,Name
Table Entry:
ID,Name
Table User_Entry:
UserID,EntryID
I would like to get all Entries (their ID and NAME) and a flag, that states, if a User with ID x has this Entry (via Table USER_ENTRY)
#GarethD answer is fine but I would go one step further to verify that actual UserID in User_Entry is actual valid user in User table. If you do not have foreign keys on the table it is possible that you have UserID that does not exists in User table. To enforce that check you can join both tables and verify Id from User table in the following manner.
SELECT e.EntryID
,e.NAME
,CASE WHEN u.ID IS NULL THEN 0 ELSE 1 AS UserFlag
FROM Entry AS e
LEFT OUTER JOIN User_Entry AS ue
ON e.id = ue.EntryID
LEFT OUTER JOIN User AS u
ON ue.UserID = u.ID
To go even further you can write case statement to can find bad records by checking both UserID in User_Entry table and checking ID in User table.
SELECT e.EntryID
,e.NAME
,CASE WHEN u.ID IS NULL THEN 0 ELSE 1 AS UserFlag
,CASE WHEN ue.UserId IS NOT NULL AND u.ID IS NULL THEN 1 ELSE 0 END AS InvalidUserID
FROM Entry AS e
LEFT OUTER JOIN User_Entry AS ue
ON e.id = ue.EntryID
LEFT OUTER JOIN User AS u
ON ue.UserID = u.ID
You would need to select from your entry table to get all your entries, and then left join to your user_entry table to find out if a particular user has that entry:
SELECT e.ID,
e.Name,
CASE WHEN ue.EntryID IS NULL THEN 0 ELSE 1 END AS UserFlag
FROM Entry AS e
LEFT JOIN user_Entry AS ue
ON ue.EntryID = e.ID
AND ue.UserID = x
You actually don't need Table C to link the ID's together. This is exactly what a SQL JOIN is for! Try:
SELECT * FROM table_a JOIN table_b WHERE table_a.id = table_b.id
Related
I am trying to do a search functionalities that involves three tables.
Searching for users and returning wheather the user id 1 is a friend of the returned users. Also The returned users is being filtered from a third table where it checks tag of that users.
So I can say, "Return users who has tag 'Programming', 'Php'
in userinterests table and also if the returned user is a friend of usr id 1 or not "
I am trying to use the bellow query but getting Column 'id' in IN/ALL/ANY subquery is ambiguous
If I remove the left join then it works.
SELECT n.id, n.firstName, n.lastName, t.id, t.tag, t.user_id, if(id in (
SELECT u.id as id from friends f, users u
WHERE CASE
WHEN f.following_id=1
THEN f.follower_id = u.id
WHEN f.follower_id=1
THEN f.following_id = u.id
END
AND
f.status= 2
), "Yes", "No") as isFriend
FROM users n
LEFT JOIN userinterests t on n.id = t.id
WHERE t.tag in ('Programming', 'Php')
Thank you for your time :)
Qualify all your column names. You seem to know this, because all other column names are qualified.
I'm not sure if your logic is correct, but you can fix the error by qualifying the column name:
SELECT . . .
(CASE WHEN n.id IN (SELECT u.id as id
FROM friends f CROSS JOIN
users u
WHERE CASE WHEN f.following_id=1
THEN f.follower_id = u.id
WHEN f.follower_id=1
THEN f.following_id = u.id
END
) AND
f.status= 2
THEN 'Yes' ELSE 'No'
END) as isFriend
. . .
This is the way I will go for your approach:
1) I used INNER JOIN instead of LEFT JOIN for skip users that are not related to tags: Programming and Php.
2) I replaced the logic to find the set of friends related to user with id equal to 1.
SELECT
n.id,
n.firstName,
n.lastName,
t.id,
t.tag,
t.user_id,
IF(
n.id IN (SELECT follower_id FROM friends WHERE status = 2 AND following_id = 1
UNION
SELECT following_id FROM friends WHERE status = 2 AND follower_id = 1),
"Yes",
"No"
) AS isFriend
FROM
users n
INNER JOIN
userinterests t ON n.id = t.id AND t.tag IN ('Programming', 'Php')
Just curious, whats is the meaning of status = 2 ?
I have the following SELECT UPDATE statement from MySQL
UPDATE table_Learning l
INNER JOIN (select ULN, id from table_users group by ULN having count(ULN) =1) u
ON l.ULN = u.ULN
set l.user_id=u.id
WHERE l.user_id is null
The problem is, it is so slow that it times out, and basically does not work.
I am sure it is to do with the line:
INNER JOIN (select ULN, id from table_users group by ULN having count(ULN) =1) u
and specifically because there is both a GROUP BY and a HAVING clause in this inner select, and from what I have read, because INNER JOINS are very slow with MySQL.
My overall aim is to:
Populate the userID's that are null in table_learning
To do so using the userID's in table_users
To Join on the field named ULN in both tables
To only populate the fields where the ULN is unique in table_users eg if more than one user has this ULN, then do not populate the user_id in table_learning
This is your query:
UPDATE table_Learning l INNER JOIN
(select ULN, id
from table_users
group by ULN
having count(ULN) = 1
) u
ON l.ULN = u.ULN
set l.user_id=u.id
WHERE l.user_id is null;
In MySQL, the subquery is going to be expensive. An index on table_learning(user_id) might help a bit. But filtering inside the subquery could also help:
UPDATE table_Learning l INNER JOIN
(select ULN, id
from table_users
where exists (select 1
from table_learning tl
where tl.ULN = u.uln and tl.user_id is null
)
group by ULN
having count(ULN) = 1
) u
ON l.ULN = u.ULN
set l.user_id=u.id
WHERE l.user_id is null;
For this, you want a composite index on table_learning(ULN, user_id).
I have two tables as follows
user [ ID , username ]
relationship [ user1_id(FK) , user2_id (FK) , status ]
I am trying to get the username by using either user1_id or user2_id where the status = 1 from relationship table. user1_id and user2_id are both IDs from the user table. The following query is failing and I am not sure where it's going wrong.
SELECT
U.username,
(R.first_user_id, R.second_user_id AS friends)
FROM
user U,
`relationship` R
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id`)
AND (`status` = 1 AND U.ID = friends)
returns both names of users in a relationship with a status of 1.
this also assumes that if a relationship record exists, both users must be in the user table.
SELECT U1.UserName, U2.username
FROM Relationship R
INNER JOIN USER U1
on R.User1_ID = U1.user_ID
INNER JOIN USER U2
and R.User2_ID = U2.user_ID
WHERE R.Status=1
It looks like you may be trying to get the usernames of all users that have a relationship with a certain specified user, regardless of the order of user IDs in the relationship record. That could be this:
SELECT
U.username,
U.first_user_id,
FROM
user U
JOIN `relationship` R
ON R.first_user_id = U.ID
WHERE
(R.`second_user_id` = {$userID})
AND (`status` = 1)
UNION ALL
SELECT
U.username,
U.second_user_id,
FROM
user U
JOIN `relationship` R
ON R.second_user_id = U.ID
WHERE
(R.`first_user_id` = {$userID})
AND (`status` = 1)
If that produces duplicates (or could do) and you don't want it to do, then change the UNION ALL to a straight UNION.
I have succeeded based on xQbert answer:
SELECT
U1.username,
U2.username
AS user_friend
FROM
Relationship R
INNER JOIN
user U1
ON
R.first_user_id = U1.ID
INNER JOIN
user U2
ON
R.second_user_id = U2.ID
WHERE (R.`first_user_id` = {$userID} OR R.`second_user_id` = {$userID})
AND `status` = 1
I am having problem with fetching data from multiple tables with some conditions in MySQL.
I have follwing three tables:
Like Table
Like_id photoID userID
1 1 1
2 2 2
3 2 1
BookMark Table
bookmark_id photoID userID
1 1 1
2 2 2
3 2 1
Users Table
User_id Name Email
1 Max B maxb#gmailcom
2 Tom Smith toms#gmailcom
CONDITIONS:
At first i want to check whether there is any data from the LIKE table for the userID = 2. If there is no data it should return "false" otherwise it should return "true".
Similarly, i want to check whether there is any data from the BOOKMARK table for the userID = 2. If there is no data it should return "false" otherwise it should return "true".
Finally, i want to fetch the Name and Email from the USERS table for the userID = 2.
WANTED:
I want to achieve all these information in a SINGLE QUERY with the above mentioned conditions from these three tables.
SO FAR tried with this QUERY:
select Like.Like_id from (Like left join Users on Like.userID = Users.User_id)
left join BookMark on Users.User_id = BookMark.bookmark_id
where Users.User_id = 2
With #Gervs suggestion:
SELECT
u.user_id,
u.name,
u.email,
(CASE WHEN ISNULL(l.user_id) THEN 'false' ELSE 'true' END) AS 'likes',
(CASE WHEN ISNULL(b.user_id) THEN 'false' ELSE 'true' END) AS 'bookmarks'
FROM
users u
LEFT JOIN
likes l
ON u.user_id = l.user_id
LEFT JOIN
bookmarks
ON u.user_id = b.user_id
WHERE u.user_id = 2
GROUP BY u.user_id
What will be the easiest but efficient single query to fetch these information?
Will VIEW be a best option for these conditions?
Advanced thanks for your participation.
You can inner join both like table and bookmark table on users table, that is if you want only users that have entries in both tables.
SELECT
u.user_id,
u.name,
u.email,
COUNT(l.user_id) likes,
COUNT(b.user_id) bookmarks
FROM
users u
JOIN
likes l
ON u.user_id = l.user_id
JOIN
bookmarks b
ON u.user_id = b.user_id
WHERE u.user_id = 2
GROUP BY u.user_id
If you always want the user, just change the inner joins into left joins and likes and/or bookmarks will be zero if no entries are found
SELECT
u.user_id,
u.name,
u.email,
CASE WHEN COUNT(l.user_id) > 0 THEN 'true' ELSE 'false' END likes,
CASE WHEN COUNT(b.user_id) > 0 THEN 'true' ELSE 'false' END bookmarks
FROM
users u
LEFT JOIN
likes l
ON u.user_id = l.user_id
LEFT JOIN
bookmarks b
ON u.user_id = b.user_id
WHERE u.user_id = 2
GROUP BY u.user_id
I have a SQL query that left joins a table in different ways depending on a condition.
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
IF (u.id=m.user2ID)
LEFT JOIN users AS u ON u.id = m.user1ID
ELSE
LEFT JOIN users AS u ON u.id = m.user2ID
ENDIF
WHERE m.user1ID=2 OR m.user2ID=2
matches is a table with integer columns user1ID and user2ID. users is a table containing users of my web application. users has a VARCHAR field called first_name.
The intention of this query is to get the names of the users matched with the current user.
However, MySQL returns this error:
#1064 - You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version for
the right syntax to use near 'IF (u.id=m.user2ID) LEFT JOIN users
AS u ON u.id = m.user1ID ELSE LEFT JOIN user' at line 3
Why?
Specify the condition as part of the ON clause:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON (u.id=m.user2ID and u.id = m.user1ID) or (u.id<>m.user2ID and u.id = m.user2ID)
WHERE m.user1ID=2 OR m.user2ID=2
Another way to do the same thing:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON IF(u.id=m.user2ID,u.id = m.user1ID,u.id = m.user2ID)
WHERE m.user1ID=2 OR m.user2ID=2
Use this query:
SELECT m.id, u.first_name AS otherUser FROM matches AS m LEFT
JOIN users AS u ON u.id = m.user1ID AND u.id=m.user2ID LEFT JOIN users
AS u1 ON u1.id = m.user2ID WHERE m.user1ID=2 OR m.user2ID=2
Updated query:
SELECT m.id, u.first_name AS otherUser
FROM matches AS m
LEFT JOIN users AS u ON u.id = (CASE WHEN u.id=m.user2ID
THEN m.user1ID
ELSE m.user2ID
END)
WHERE m.user1ID=2 OR m.user2ID=2
Check this Source.
Also check this MYSQL Inner Join if statement . It might be helpful for you.
You can also have two LEFT JOIN on the same table like this...
LEFT JOIN users AS u ON u.id = m.user1ID
LEFT JOIN users AS u2 ON u2.id = m.user2ID
This is an alternative to using IF statements.
You can not use the IF THEN ELSE END IF-stuff in a SELECT in this way. However, you can use it in stored procedures and functions.
I would JOIN u.id with both m.user1ID and m.user2ID and use DISTINCT to avoid duplicates.
There is a IF() which you can use in SELECTs, but you can not do flow control with IF().
Thanks,
It worked for me. Tried something else like below :
**
Create table TEMP1 (ID INT,T_MONTH INT,T_YEAR INT)
INSERT INTO TEMP1 VALUES(1,1,2001)
INSERT INTO TEMP1 VALUES(2,2,2001)
INSERT INTO TEMP1 VALUES(3,3,2001)
**
CREATE TABLE TEMP2 (T_MONTH INT,T_YEAR INT,FREQUENCY CHAR(1),VAL FLOAT)
INSERT INTO TEMP2 VALUES(1,2001,'M',1.1)
INSERT INTO TEMP2 VALUES(3,2001,'M',1.2)
INSERT INTO TEMP2 VALUES(3,2001,'Q',1.3)
INSERT INTO TEMP2 VALUES(12,2001,'A',1.4)
SELECT * FROM TEMP1 L JOIN TEMP2 H
ON L.T_YEAR = H.T_YEAR
OR (L.T_MONTH = (CASE WHEN H.FREQUENCY='M'
THEN H.T_MONTH
END)
OR dbo.GetQuarterFromMonth(L.T_MONTH) = (CASE WHEN H.FREQUENCY = 'Q'
THEN dbo.GetQuarterFromMonth(H.T_MONTH)
END))
WHERE H.FREQUENCY = 'Q'
Here GetQuarterFromMonth is a user defined funtion which returns Quarter for a particular month.
The objective of above query is to inflate the value of Quarter for all the months in table 1. If frequency is annual then in that case the value should be inflated for all the months 1-12 of table 1 which is achieved through first join condition. In case frequency is Monthly then each month from table1 should be mapped to table2. The only unique case is handling quarter frequency.