5

以下 MySQL 查询:

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

…返回一个错误:

Unknown column 'sID' in 'IN/ALL/ANY subquery'

我不明白我在这里做错了什么。这个sID东西不应该是一个列,而是我通过执行创建的“别名”(这叫什么?)(select siteID from users where userID = uID) as sID。它甚至不在IN子查询中。

有任何想法吗?


编辑: @Roland:感谢您的评论。我有三个表actionsuserssites。该表actions包含一个userID字段,该字段对应于users表中的一个条目。此表 ( users) 中的每个用户都有一个siteID. 我正在尝试从actions表中选择最新的操作,并将它们链接到usersandsites表以找出执行这些操作的人员以及在哪个站点上执行的操作。希望这是有道理的:)

4

6 回答 6

12

您要么需要将其包含在子查询中:

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

,或者,更好的是,将其重写为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

创建以下索引:

actions (timestamp)
users (userId)
sites (foo, siteID)
于 2009-12-30T16:19:15.127 回答
3

在查询处理器完成 Select 子句并构建第一个中间结果集之前,不会建立列别名,因此只能在 group By 中引用它,(因为 group By 子句在该中间结果集上操作)如果你想不要以这种方式使用它,将别名放在子查询中,然后它将在子查询生成的结果集中,因此外部查询可以访问。为了显示

(这不是执行此查询的最简单方法,但它说明了如何从子查询中建立和使用列别名)

 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 
于 2009-12-30T16:18:43.837 回答
1

尝试以下操作:

SELECT
       a.userID as uID
       ,u.siteID as sID
    FROM
       actions as a
    INNER JOIN
       users as u ON u.userID=a.userID
    WHERE
       u.siteID IN (SELECT siteID FROM sites WHERE foo = 'bar')
    ORDER BY
       a.timestamp DESC
    LIMIT 100
于 2009-12-30T16:16:19.070 回答
0

尝试以下

SELECT 
       a.userID as uID 
       ,u.siteID as sID 
    FROM 
       actions as a 
    INNER JOIN 
       users as u ON u.userID = a.userID 
    INNER JOIN
        sites as s ON u.siteID = s.siteID   
    WHERE 
       s.foo = 'bar'
    ORDER BY 
       a.timestamp DESC 
    LIMIT 100 

如果您希望稍后使用选择部分中的字段,您可以尝试子选择

SELECT  One,
        Two,
        One + Two as Three
FROM    (
            SELECT  1 AS One,
                    2 as Two
        ) sub
于 2009-12-30T16:19:45.050 回答
0

我认为错误的原因是别名对 WHERE 指令不可用,这就是我们有 HAVING 的原因。

select `userID` as uID,
(select `siteID` from `users` where `userID` = uID) as `sID`,
from `actions`
HAVING `sID` in (select `siteID` from `sites` where `foo` = "bar")
order by `timestamp` desc limit 100

尽管我也同意您的查询可以更好地结构化的其他答案。

于 2009-12-30T16:19:58.140 回答
0

我不知道这在 11 年前是否不在 SQL 标准中,但我发现它是使用 HAVING 的最简单方法:

select `userID` as uID,
(select `siteID` from `users` where `userID` = uID) as `sID`,
from `actions`
order by `timestamp` desc limit 100
HAVING `sID` in (select `siteID` from `sites` where `foo` = "bar")
于 2020-08-26T11:17:37.450 回答