Что не так с этим запросом MySQL? SELECT * AS `x`, как снова использовать x позже?
Следующий запрос 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: Спасибо за ваш комментарий. У меня есть три стола, actions
, users
а также sites
, Стол actions
содержит userID
поле, которое соответствует записи в users
Таблица. Каждый пользователь в этой таблице (users
) имеет siteID
, Я пытаюсь выбрать последние действия из actions
таблицу, и связать их с users
а также sites
таблица, чтобы узнать, кто выполнял эти действия и на каком сайте. Надеюсь, что это имеет смысл:)
5 ответов
Вам либо нужно заключить его в подзапрос:
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)
Псевдоним столбца не устанавливается до тех пор, пока обработчик запросов не завершит предложение Select и не создаст первый промежуточный набор результатов, поэтому на него можно ссылаться только в группе 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
Попробуйте следующее:
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
Попробуйте следующее
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
Я не знаю, не было ли этого в стандарте SQL 11 лет назад, но я нашел, что это самый простой способ использовать 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")
Я думаю, что причина ошибки в том, что псевдоним недоступен для инструкции 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
Хотя я также согласен с другими ответами, что ваш запрос может быть лучше структурирован.