В MySQL 5.0 почему возникает следующая ошибка при попытке создать представление с подзапросом в предложении FROM?
ОШИБКА 1349 (HY000): Просмотр SELECT содержит подзапрос в предложении FROM
Если это ограничение для механизма MySQL, то почему они еще не реализовали эту функцию?
Кроме того, какие хорошие способы обхода этого ограничения?
Существуют ли какие-либо обходные пути, которые работают для любого подзапроса в предложении FROM, или есть некоторые запросы, которые не могут быть выражены без использования подзапроса в предложении FROM?
Пример запроса (был похоронен в комментарии):
SELECT temp.UserName
FROM (SELECT u1.name as UserName, COUNT(m1.UserFromId) as SentCount
FROM Message m1, User u1
WHERE u1.uid = m1.UserFromId
Group BY u1.name HAVING SentCount > 3 ) as temp
Ответ 1
Ваш запрос не может быть записан так:
SELECT u1.name as UserName from Message m1, User u1
WHERE u1.uid = m1.UserFromID GROUP BY u1.name HAVING count(m1.UserFromId)>3
Это также должно помочь с известными проблемами скорости с подзапросами в MySQL
Ответ 2
У меня была та же проблема. Я хотел создать представление, чтобы показать информацию за последний год, из таблицы с записями с 2009 по 2011 год. Здесь исходный запрос:
SELECT a.*
FROM a
JOIN (
SELECT a.alias, MAX(a.year) as max_year
FROM a
GROUP BY a.alias
) b
ON a.alias=b.alias and a.year=b.max_year
Контур решения:
- создать представление для каждого подзапроса
- заменить подзапросы этими представлениями
Здесь запрос на решение:
CREATE VIEW v_max_year AS
SELECT alias, MAX(year) as max_year
FROM a
GROUP BY a.alias;
CREATE VIEW v_latest_info AS
SELECT a.*
FROM a
JOIN v_max_year b
ON a.alias=b.alias and a.year=b.max_year;
Он отлично работает на mysql 5.0.45 без значительного штрафа за скорость (по сравнению с выполнением
исходный подзапрос выбирается без каких-либо просмотров).
Ответ 3
Это, как известно, известная проблема.
http://dev.mysql.com/doc/refman/5.1/en/unnamed-views.html
http://bugs.mysql.com/bug.php?id=16757
Многие запросы IN могут быть переписаны как (левые внешние) объединения, так и IS (NOT) NULL. например
SELECT * FROM FOO WHERE ID IN (SELECT ID FROM FOO2)
можно переписать как
SELECT FOO.* FROM FOO JOIN FOO2 ON FOO.ID=FOO2.ID
или
SELECT * FROM FOO WHERE ID NOT IN (SELECT ID FROM FOO2)
может быть
SELECT FOO.* FROM FOO
LEFT OUTER JOIN FOO2
ON FOO.ID=FOO2.ID WHERE FOO.ID IS NULL
Ответ 4
создать представление для каждого подзапроса - это путь. Это работает как шарм.
Ответ 5
Вы можете обойти это, создав отдельный VIEW для любого подзапроса, который вы хотите использовать, а затем присоединитесь к тому, что вы создаете.
Вот пример:
http://blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-clause/
Это очень удобно, так как вы, скорее всего, захотите снова его использовать и сможете сохранить свой SQL DRY.