В MySQL, как я могу создать JOIN внутри подзапроса? - PullRequest
0 голосов
/ 08 февраля 2012

Рабочий образец с использованием одной таблицы

SELECT t.* FROM (
  SELECT
    TITLE.name, 
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE 
) t
WHERE 98 BETWEEN t.Lower AND t.Upper
ORDER BY ABS(98 - t.Value) ASC
LIMIT 5

Требуемый пример работы с 3 таблицами (необходимо исправить / помочь)

SELECT t.* FROM (
  SELECT
    TITLE.name, ALBUM.year, GENRE.Type
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE, ALBUM, GENRE 
) t
WHERE ALBUM.ID=GENRE.ID AND TITLE.ID=ALBUM.ID  
AND 98 BETWEEN t.Lower AND t.Upper
ORDER BY ABS(98 - t.Value) ASC;

Я получаю следующую ошибку:

ОШИБКА 1054 (42S22): неизвестный столбец 'ALBUM.ID' в 'выражении where'

Ответы [ 3 ]

3 голосов
/ 08 февраля 2012

Это логично: ваш подзапрос создает одну таблицу t, а после слов вы пытаетесь сослаться на таблицу ALBUM.Нет ALBUM, есть только t

Самое быстрое решение - переместить предложение WHERE для JOIN, в которое оно входит: в подзапрос.

SELECT t.* FROM (
  SELECT
    TITLE.name, ALBUM.year, GENRE.Type
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE, ALBUM, GENRE 
  WHERE ALBUM.ID=GENRE.ID AND TITLE.ID=ALBUM.ID  
) t
WHERE 98 BETWEEN t.Lower AND t.Upper
ORDER BY ABS(98 - t.Value) ASC;

Сам запрос не такой красивый, хотя ... почему бы не попробовать это вместо этого:

  SELECT
    TITLE.name, ALBUM.year, GENRE.Type
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE
   JOIN ALBUM
    ON TITLE.ID=ALBUM.ID  
   JOIN GENRE 
    ON ALBUM.ID=GENRE.ID 
  WHERE 98 BETWEEN Lower AND Upper
  ORDER BY ABS(98 - Value) ASC;
  • Удален ненужный подзапрос
  • Используется JOIN в стиле SQL-92 вместо SQL-JOIN в стиле 89 (декартово произведение с предложением where)
2 голосов
/ 08 февраля 2012

Посмотрите на ваш запрос: вы определяете подзапрос, называемый T, который создает декартово произведение между таблицами TITLE, ALBUM и GENRE. Затем вы выбираете из этого подзапроса и пытаетесь применить предложение WHERE к TITLE, ALBUM и GENRE ... Но эти таблицы больше не находятся в области видимости!

Попробуйте вместо этого:

SELECT t.* FROM (
  SELECT
    TITLE.name, ALBUM.year, GENRE.Type
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE, ALBUM, GENRE 
  WHERE ALBUM.ID=GENRE.ID AND TITLE.ID=ALBUM.ID  
) t
WHERE 98 BETWEEN t.Lower AND t.Upper
ORDER BY ABS(98 - t.Value) ASC;
1 голос
/ 08 февраля 2012

Переместить предложение WHERE во внутренний запрос.

SELECT t.* FROM (
  SELECT
    TITLE.name, ALBUM.year, GENRE.Type
    (TITLE.value-TITLE.msp) AS Lower, 
    (TITLE.value+TITLE.msp) AS Upper,
    (TITLE.value) AS Value
  FROM TITLE, ALBUM, GENRE 
  WHERE ALBUM.ID=GENRE.ID AND TITLE.ID=ALBUM.ID  
) t
AND 98 BETWEEN t.Lower AND t.Upper
ORDER BY ABS(98 - t.Value) ASC;
...