The following MySQL query:
select `userID` as uID,
(select `siteID` from `users` where `userID` = uID) as `sID`,
from `actions`
where `sID` in (select `siteID` from `sites` where `foo` = "bar")
order by `timestamp` desc limit 100
…returns an error:
Unknown column 'sID' in 'IN/ALL/ANY subquery'
I don't understand what I'm doing wrong here. The sID
thing is not supposed to be a column, but the 'alias' (what is this called?) I created by executing (select siteID from users where userID = uID) as sID
. And it’s not even inside the IN
subquery.
Any ideas?
Edit: @Roland: Thanks for your comment. I have three tables, actions
, users
and sites
. The table actions
contains a userID
field, which corresponds to an entry in the users
table. Every user in this table (users
) has a siteID
.
I'm trying to select the latest actions from the actions
table, and link them to the users
and sites
table to find out who performed those actions, and on which site. Hope that makes sense :)
By using SELECT * you can be returning unnecessary data that will just be ignored but fetching that data is not free of cost. This results in some wasteful IO cycles at the DB end, since you will be reading all of that data off the pages, then perhaps you could have read the data from index pages.
The SELECT statement is used to select data from a database. The data returned is stored in a result table, called the result-set.
x is the name given to the resulting table which comes from the inner select. The name could be any valid table name not just x . Subqueries are legal in a SELECT statement's FROM clause. The actual syntax is: SELECT ...
MySQL stored functions only return a single scalar value. They cannot return result sets. Functions can be used in a scalar expression context. You can use a stored procedure to return a result set, but you can't use it in an expression.
You either need to enclose it into a subquery:
SELECT *
FROM (
SELECT userID as uID, (select siteID from users where userID = actions.userID) as sID,
FROM actions
) q
WHERE sID IN (select siteID from sites where foo = "bar")
ORDER BY
timestamp DESC
LIMIT 100
, or, better, rewrite it as a JOIN
SELECT a.userId, u.siteID
FROM actions a
JOIN users u
ON u.userID = a.userID
WHERE siteID IN
(
SELECT siteID
FROM sites
WHERE foo = 'bar'
)
ORDER BY
timestamp DESC
LIMIT 100
Create the following indexes:
actions (timestamp)
users (userId)
sites (foo, siteID)
The column alias is not established until the query processor finishes the Select clause, and buiulds the first intermediate result set, so it can only be referenced in a group By, (since the group By clause operates on that intermediate result set) if you want ot use it this way, puit the alias inside the sub-query, then it will be in the resultset generated by the subquery, and therefore accessible to the outer query. To illustrate
(This is not the simplest way to do this query but it illustrates how to establish and use a column alias from a subquery)
select a.userID as uID, z.Sid
from actions a
Join (select userID, siteID as sid1 from users) Z,
On z.userID = a.userID
where Z.sID in (select siteID from sites where foo = "bar")
order by timestamp desc limit 100
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With