MySQL:Просмотр с подзапросом в ограничении предложения FROM

StackOverflow https://stackoverflow.com/questions/206062

Вопрос

Почему в 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
Это было полезно?

Решение

Нельзя ли запрос в вашем комментарии записать так:

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.

Другие советы

У меня такая же проблема.Я хотел создать представление для отображения информации за последний год из таблицы с записями с 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

Схема решения:

  1. создать представление для каждого подзапроса
  2. замените подзапросы этими представлениями

Вот запрос решения:

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, без большого штрафа на скорость (по сравнению с выполнением исходного Sub-Query Select без каких-либо представлений).

Похоже, это известная проблема.

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

создать представление для каждого подзапроса - это путь.Получил это работает как шарм.

Вы можете обойти эту проблему, создав отдельный VIEW для любого подзапроса, который вы хотите использовать, а затем присоединитесь к нему в создаваемом VIEW.Вот пример:http://blog.gruffdavies.com/2015/01/25/a-neat-mysql-hack-to-create-a-view-with-subquery-in-the-from-clause/

Это очень удобно, так как вы, скорее всего, все равно захотите использовать его повторно, и поможет вам сохранить SQL DRY.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top