Help with MySQL Query? - sql

I have two tables rooms and users. I want to get only rooms.room_id, users.user_name with user_id = 1. I can get the result of all users with following sql...
select rooms.room_id,
rooms.user_id,
users.user_name
from rooms
LEFT JOIN users ON rooms.user_id = users.user_id
When I do like this to filter the result with user_id = 1 ... I got error.
select rooms.room_id,
rooms.user_id,
users.user_name
from rooms where rooms.user_id = 1
LEFT JOIN users ON rooms.user_id = users.user_id
What should I do?

ANSI-92 JOIN syntax (when you see LEFT JOIN ...) dictates that the WHERE clause comes after the JOIN(s):
SELECT r.room_id,
r.user_id,
u.user_name
FROM ROOMS r
LEFT JOIN users ON u.user_id = r.user_id
WHERE r.user_id = 1
You were close.

Write the query as:
select rooms.room_id,
rooms.user_id,
users.user_name
from rooms
LEFT JOIN users ON rooms.user_id = users.user_id
WHERE roows.user_id = 1

Try:
select rooms.room_id,
rooms.user_id,
users.user_name
from rooms
LEFT JOIN users ON rooms.user_id = users.user_id
WHERE rooms.user_id = 1
The syntax of a simple SQL SELECT query is:
SELECT [a list of fields]
FROM [a single table name maybe with an alias, or a join of tables]
WHERE [a filter, applied over some fields of the tables in the FROM clause]
You could read an introductory tutorial here.

It helps to state what error you get.
I would guess that the problem is that the where clause needs to be after the joins
select rooms.room_id,
rooms.user_id,
users.user_name
from rooms
LEFT JOIN users ON rooms.user_id = users.user_id
where rooms.user_id = 1

Related

How to replace exist in Hive with two correlated subqueries

I have a query that looks like this
SELECT u.id, COUNT(*)
FROM users u, posts p
WHERE u.id = p.owneruserid
AND EXISTS (SELECT COUNT(*) as num
FROM postlinks pl
WHERE pl.postid = p.id
GROUP BY pl.id
HAVING num > 1) --correlated subquery 1
AND EXISTS (SELECT *
FROM comments c
WHERE c.postid = p.id); --correlated subquery 2
GROUP BY u.id
I researched and read that in Hive IN or EXIST are not supported statements. I read that a workaround for this would be to use a LEFT JOIN. I have tried this but I am having trouble with the GROUP BY u.id. I read that this needs to be paired always with an aggregation function like COUNT() however I'm not sure how I can rewrite this query so as to get it to work. All the other examples I have seen online do not seem to be as complicated as this one.
Like you said, you can convert them to left join or may be left join since they uses exists in both subquery. Simply convert your subqueries to inline view and join them with original tables.
SELECT u.id, COUNT(*)
FROM users u
inner join posts p on u.id = p.owneruserid
left outer join (SELECT COUNT(*) as num, pl.postid postid
FROM postlinks pl
GROUP BY pl.postid
HAVING num > 1) pl ON pl.postid = p.id --correlated subquery 1 with left join
left outer join (SELECT postid FROM comments c GROUP BY postid)c ON c.postid = p.id --correlated subquery 2 with left join
WHERE ( c.postid is not null AND pl.postid is not null) -- this ensure data exists in both subquery
GROUP BY u.id
With left join, there may be chance of duplicates, you can use group by in subqry2 to avoid it.

Distinct Count with data from another table

I have 4 tables
All ID related things are ints and the rest are texts.
I want to count the number of albums the user is tagged at so if a user is tagged in album1 once album2 once and album3 once it will show 3 and if more in any of them it will still show 3.
I tried to do:
SELECT COUNT(DISTINCT ALBUM_ID) FROM PICTURES WHERE ID=(SELECT PICTURE_ID FROM TAGS WHERE USER_ID=userId);
But this returned 1 although it was supposed to return 3 and the same happened without DISTINCT.
How can I get the amount?
EDIT:
I want to check only one user(I have the user's ID and name)
You must join users with LEFT joins to tags and pictures and aggregate:
SELECT u.id, u.name, COUNT(DISTINCT p.album_id) counter
FROM users u
LEFT JOIN tags t ON t.user_id = u.id
LEFT JOIN pictures p ON p.id = t.picture_id
GROUP BY u.id, u.name
If you want the result for a specific user only:
SELECT u.id, u.name, COUNT(DISTINCT p.album_id) counter
FROM users u
LEFT JOIN tags t ON t.user_id = u.id
LEFT JOIN pictures p ON p.id = t.picture_id
WHERE u.id = ?
GROUP BY u.id, u.name -- you may omit this line, because SQLite allows it
Or with a correlated subquery:
SELECT u.id, u.name,
(
SELECT COUNT(DISTINCT p.album_id)
FROM tags t INNER JOIN pictures p
ON p.id = t.picture_id
WHERE t.user_id = u.id
) counter
FROM users u
WHERE u.id = ?
Replace ? with the id of the user that you want.

SQL INNER JOIN exception

I'm new to SQL queries and I'm trying to join two tables
I need to get all data of the followers of userID = 2
here's the error i get : Syntax error: Encountered "INNER" at line 1, column 39.
and here's the SQL query I ran :
SELECT * FROM FOLLOWER
WHERE userID = "2"
INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID
ORDER BY USERS.follower_count ASC
The tables in my DB are :
FOLLOWER
ID
userID
Follower_userID
USERS
userID
username
password
Nickname
P.S
I'm using Apache Derby.
Thank you so much guys.
position of where clause was incorrect
structure of SELECT query is
SELECT fields
FROM tables
WHERE conditions
ORDER BY fields
so you query should be
SELECT *
FROM FOLLOWER INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID
WHERE userID="2"
ORDER BY USERS.follower_count ASC
Try this statement:
SELECT * FROM FOLLOWER Fl
WHERE userID="2"
INNER JOIN USERS Us ON Us.userID = Fl.Follower_userID
ORDER BY USERS.follower_count ASC
Let me know if it's works
First use join and then where.
SELECT * FROM FOLLOWER INNER JOIN USERS ON FOLLOWER.Follower_userID = USERS.userID WHERE userID=2 ORDER BY USERS.follower_count ASC
Try this
SELECT * FROM FOLLOWER
INNER JOIN USERS
ON FOLLOWER.Follower_userID = USERS.userID
WHERE FOLLOWER.userID="2"
ORDER BY USERS.follower_count ASC
Hope this helps
The Inner Join syntax
SELECT *
FROM Table1 AS T1
INNER JOIN Table2 AS T2
ON T1.Table1ColName = T2.Table2ColName
ORDER BY T1.Table1ColName
Refer this link for Inner Join
Change your query like
SELECT * FROM FOLLOWER
INNER JOIN USERS
ON FOLLOWER.Follower_userID = USERS.userID
WHERE userID="2"
ORDER BY USERS.follower_count ASC
The rules of where with join is first made all join and then give where condition which filter more data..
so your where condition just put after inner join as above all suggested.
select *
from yourtable
join yourothertable
where condition if you want
http://bytes.com/topic/sql-server/answers/850159-performance-conditions-where-clause-vs-conditions-inner-join

How do I match against multiple conditions on a table join?

I have two tables:
users attributes
id|name id|name|user_id
------- ---------------
1 |foo 1 |bla | 1
2 |bar 1 |blub| 1
1 |bla | 2
How do I create a query gives users with both the "bla" AND "blub" attributes?
In this case it should only return the user "foo".
I know that the data is not normalized.
SELECT u.*, a.id, b.Id, a.name, b.name FROM users u
JOIN attributes a
ON a.User_id = u.User_id AND a.name = 'bla'
JOIN attributes b
ON u.User_Id = b.User_id AND b.name = 'blub'
Assuming an attribute association to a user is unique...
if you need 3 conditions to be true add the conditions to the in and adjust count up 1.
SELECT u.name
FROM users u
INNER JOIN attributes a on A.user_Id = u.id
WHERE a.name in ('bla','blub')
GROUP by u.name
HAVING count(*)=2
and if you don't have an unique association, or you need to join to another table you could always do...
SELECT u.name
FROM users u
INNER JOIN attributes a on A.user_Id = u.id
WHERE a.name in ('bla','blub')
GROUP by u.name
HAVING count(distinct A.name)=2
for a slight performance hit. but this allows you to join and get back additional fields which others have indicated was a detriment to this method.
This allows for scaling of the solution instead of incurring the cost of joining each time to different tables. In addition, if you needed thirty-something values to associate, you may run into restrictions on the number of allowed joins.
SELECT U.NAME
FROM USERS U
INNER JOIN
ATTRIBUTES A1
ON U.ID = A1.USER_ID
INNER JOIN
ATTRIBUTES A2
ON U.ID = A2.USER_ID
WHERE A1.NAME = 'bla'
AND A2.NAME = 'blub'
You can use the INTERSECT operator
SELECT
u.id
,u.name
FROM users AS u
INNER JOIN attributes AS a
ON u.id = a.user_id
WHERE a.name = 'bla'
INTERSECT
SELECT
u.id
,u.name
FROM users AS u
INNER JOIN attributes AS a
ON u.id = a.user_id
WHERE a.name = 'blub'
;
Here is a demo on SQL Fiddle: http://sqlfiddle.com/#!6/68986/5
More info on SET operations in SQL: http://en.wikipedia.org/wiki/Set_operations_(SQL)
SELECT u.name
FROM attributes a
JOIN users u
ON u.id = a.user_id
WHERE a.name IN ('bla','bulb')

Why does this query return nothing?

This query works fine but I'm having trouble trying to figure out why it does not return anything if the user does not have any categories in the table "user_categories"? This is the table structure:
users: user id, username, user city
categories: category id, category name
user_categories: user id, category id
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
INNER JOIN user_categories ON users.user_id = user_categories.user_id
INNER JOIN categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY users.user_id
LIMIT 10
I just need for the new column "categories" to be empty if no rows existed for the user_id in user_categories...
Thanks!
You are using the wrong type of join - inner join will only succeed if a match is found in both tables. Instead, you want to try an outer join. Try something like this:
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
LEFT OUTER JOIN user_categories ON users.user_id = user_categories.user_id
LEFT OUTER JOIN categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY users.user_id
LIMIT 10
The Wikipedia SQL JOIN article is a pretty decent summary of the join types available.
SELECT users.*, GROUP_CONCAT(categories.category_name) AS categories
FROM users
LEFT JOIN
user_categories ON users.user_id = user_categories.user_id
LEFT JOIN
categories ON user_categories.category_id = categories.category_id
WHERE users.user_city = 'brooklyn'
GROUP BY
users.user_id
LIMIT 10
Note that on a MyISAM table, a subquery solution will probably be more efficient:
SELECT users.*,
(
SELECT GROUP_CONCAT(category_name)
FROM user_categories uc
JOIN categories c
ON c.category_id = uc.category_id
WHERE uc.user_id = users.id
) AS categories
FROM users
WHERE users.user_city = 'brooklyn'
ORDER BY
user_id
LIMIT 10
See this article in my blog for more detail:
Aggregates: subqueries vs. GROUP BY
An inner join will not return a record if there is not a record in both tables. You may be wanting a left outer join.
That's because you use an INNER JOIN to user_categories. If you use a LEFT JOIN, null data will be returned for that table if there is no corresponding ID for the user.