在MySQL中如何在子查询中创建JOIN?

时间:2012-02-08 18:22:52

标签: mysql database subquery union

使用一个表

的工作样本
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;

我收到以下错误:

  

ERROR 1054(42S22):'where子句'中的未知列'ALBUM.ID'

3 个答案:

答案 0 :(得分:3)

这是合乎逻辑的:您的子查询会创建一个表t,之后您会尝试引用表ALBUM。没有ALBUM,只有t

最快修复它来移动它所属的JOIN的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
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;
  • 删除了不必要的子查询
  • 使用SQL-92样式JOIN而不是SQL-89样式JOIN(带有where子句的笛卡尔积)

答案 1 :(得分:2)

查看您的查询:您正在定义一个名为T的子查询,该查询在表TITLEALBUMGENRE之间执行cartesian product然后您从该子查询中进行选择,并尝试在WHERETITLEALBUM上应用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;

答案 2 :(得分:1)

将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;