【问题标题】:SQL Join three tablesSQL Join 三张表
【发布时间】:2011-12-22 10:49:56
【问题描述】:

我正在一点一点地学习高级 SQL 查询,但我被一个问题难住了:

我有三个表:newsauthorimagesnews 表 (newsID) 中的每个字段都是一个新闻故事,然后在 author 表 (authorID) 中具有关联的作者,并且可以在 images 表中关联任意数量的图像。每个图像都有并关联 (newsID)。因此,每个故事都有一个作者,但可以有多个图像。

我想列出所有新闻报道并只使用一个图像作为缩略图。问题是,我尝试列出 news 项目的任何 sql 查询都会得到等于 images 表中图像数量的结果,而不是 news 项目的数量。

我不知道从这里去哪里。任何帮助将不胜感激。

【问题讨论】:

  • 您可以使用LIMIT 1 来获取第一张图片。
  • 你能指定你在哪个数据库上尝试这个以及你的表的架构吗?
  • @Kerrek "Limit" 仅适用于特定风格的数据库

标签: sql database join


【解决方案1】:

如果有问题的 3 个表格是 [news]、[author] 和 [image] 并带有适当的列,那么

派生表方法

您可以有一个派生图像表来为每个新闻获取一张图像,然后将其与 newsauthor 表连接,如图所示。 这已在 SQL Server 中编写和测试。

SELECT  
      N.[newsStoryTitle]
        ,A.authorName
        ,I.imageData1
  FROM [news] N
  LEFT OUTER JOIN author A ON A.newsID = N.newsID
  LEFT OUTER JOIN 
    (
    SELECT newsID, MAX(imageData) AS imageData1 FROM [image] 
    GROUP BY newsID
    )  AS I ON I.newsID = N.newsID
ORDER BY N.newsID

如果您不需要没有任何图像的新闻,您可以将 LEFT OUTER JOIN 替换为 INNER JOIN。

相关子查询方法(由 Marcelo Cantos 建议)

如果 imageData 存储为文本或图像,则派生表中的 MAX 将不起作用。在这种情况下,您可以像这样使用相关子查询:

SELECT  N.newsStoryTitle ,
        A.authorName ,
        I.imageData
FROM    dbo.news N
        INNER JOIN dbo.author A ON N.newsID = A.newsID
        INNER JOIN dbo.image I ON N.newsID = I.newsID
WHERE   imageID = ( SELECT  MAX(imageID)
                    FROM    dbo.image
                    WHERE   newsID = N.newsID
                  )
ORDER BY n.newsID

【讨论】:

  • 这称为“派生表”
【解决方案2】:

一种选择是添加以下谓词:

FROM news JOIN images ...
...
WHERE imageID = (SELECT MAX(imageID)
                   FROM image
                  WHERE newsID = news.newsID)

请注意,这不包括没有图片的新闻项目。如果您不希望这样做,则需要对图像进行左连接并在 WHERE 上添加附加条件:

FROM news LEFT JOIN images ...
...
WHERE imageID IS NULL
   OR imageID = (SELECT MAX(imageID)
                   FROM image
                  WHERE newsID = news.newsID)

【讨论】:

  • imageID = (SELECT ...) vs. imageID in (SELECT ...) 有关系吗
  • 这不起作用,因为 where 子句总是给出一个值,因此新闻中只有一行。
  • @Kash:这是一个相关子查询。它将为每个新闻项目生成一行,即 AFAICT,即意图。
  • @Daryl:如果您在子查询中出错并返回多行,in 将很高兴返回重复的新闻项目。 = 选项会大声崩溃,提醒您出现问题。
【解决方案3】:

您可以通过子选择来修改顺序,以获得您要查找的每个新闻行的 1 张图片...

select
....
from news n
left outer join images i on i.imageID = (
    select top 1 i2.imageID 
    from images i2 
    where i2.newsID = n.newsID
    order by --??
)

【讨论】:

  • 还是没有运气。我没有得到我想要的结果集。我将不得不重新考虑这一点。感谢大家的帮助!
  • 也许重新检查您是否在正确的位置使用了表别名...i vs i2
【解决方案4】:

如果您在 mysql 中有 3 个表,并且您想将它们连接在一起。例如我有 3 张桌子 1 名学生 2 科目 3分 现在想加入有学科和分数的学生。所以我们你这个语法: select * from student inner join subject inner join score;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-09
    • 2014-10-31
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多