【问题标题】:SQL Query to get desired result from three tables从三个表中获取所需结果的 SQL 查询
【发布时间】:2012-07-21 12:40:03
【问题描述】:

我的照片库使用 5 个表格来存储不同的信息

照片、PhotoDetails、PhotoMappings、PhotoAlbum、PhotoAlbumCategory。

这是一个多语言网站,我想为相册上传一次照片并与任何语言版本的网站分享。

涉及的步骤。

  1. 我将照片添加到 Photos TABLE 中
  2. 其次,我将照片与 PhotoMapping 表中的(LanguageID、AlbumID、AlbumCategoryID)一起映射到特定相册
  3. 第三,我需要添加与特定照片相关的详细信息,例如标题、描述、日期...

为了添加详细信息,我想根据这张照片的详细信息是否在 Photodetails 表中显示特定相册下的照片的用户列表以及其他信息,例如是/否。

PhotoDetails
    [PhotoDetailsID] [int] IDENTITY(1,1) NOT NULL,
    [PhotoTitle] [nvarchar](300) NULL,
    [PhotoDesc] [nvarchar](max) NULL,
    [PhotoDate] [date] NULL,
    [PhotoVisible] [bit] NULL,
    [PhotoID] [int] NOT NULL,
    [AlbumID] [int] NULL,
    [LanguageID] [int] NULL,
    [PhotoDetailsCreatedOn] [date] NULL

PhotoMappings
    [MappingID] [int] IDENTITY(1,1) NOT NULL,
    [LanguageID] [int] NULL,
    [CategoryID] [int] NULL,
    [AlbumID] [int] NULL,
    [PhotoID] [int] NULL,

Photos
    [PhotoID] [int] IDENTITY(1,1) NOT NULL,
    [PhotoTN] [nvarchar](100) NULL,
    [PhotoLarge] [nvarchar](100) NULL,
    [PhotoGUID] [nvarchar](50) NULL,
    [PhotoCreatedOn] [date] NULL,


SELECT d.PhotoTitle,d.AlbumID,p.PhotoTN AS TN,  p.PhotoID AS PID,p.PhotoLarge AS PL,
case when d.PhotoId is null then 'NO' else 'YES' end AS [Details]
FROM Photos p  JOIN  PhotoDetails d
ON  p.PhotoId = d.PhotoId JOIN PhotoMappings m
ON  p.PhotoId = m.PhotoId WHERE d.AlbumID  = 14 and m.LanguageID = 1

我需要编写一个查询,它将显示 PhotoMapping 表中的所有记录以及 PhotoDetails 表中不存在的那些行。

我正在使用上面的查询,它得到了我想要的结果,但没有显示 PhotoDetails 表中不存在的列

我希望 OUTPUT 如下所示,假设我想要关于 AlbumID=14 & Language =1 的专辑的详细信息(我从查询中只得到前 6 行)

PhotoTitle      AlbumID TN      PID PL  Details         
Title of Photo1 14      1Icon.JPG   16  1.JPG   YES
Title of Photo2 14      2Icon.JPG   21  2.JPG   YES
Title of Photo3 14      3Icon.JPG   20  3.JPG   YES
Title of Photo4 14      4Icon.JPG   22  4.JPG   YES
Title of Photo5 14      5Icon.JPG   18  5.JPG   YES
Title of Photo6 14      6Icon.JPG   17  6.JPG   YES
Title of Photo7 14      7Icon.JPG   23  7.JPG   NO
Title of Photo8 14      8Icon.JPG   24  8.JPG   NO

如果我确实将JOIN 更改为LEFT OUTER JOINRIGHT OUTER JOIN,我将不胜感激,但输出保持不变

样本数据

映射表

MappingID   LanguageID  CategoryID  AlbumID PhotoID
1   1   7   14  16
2   1   7   14  21
3   1   7   14  20
4   1   7   14  22
5   1   7   14  19
6   1   7   14  18
7   1   7   14  17
8   1   7   14  23

来自 PhotoDetails 表的示例数据

PhotoDetailsID  PhotoTitle  PhotoDate   PhotoVisible    PhotoID AlbumID LanguageID  PhotoDetailsCreatedOn
20  Title of Photo1     2012-07-02  1   16  14  1   2012-02-07
21  Title of Photo2     2012-07-02  1   17  14  1   2012-02-07
22  Title of Photo3     2012-07-02  1   18  14  1   2012-02-07
24  Title of Photo4     2012-07-02  1   20  14  1   2012-02-07
25  Title of Photo5     2012-07-02  1   21  14  1   2012-02-07
26  Title of Photo6     2012-07-02  1   22  14  1   2012-02-07
23  Title of Photo7     2012-07-02  1   19  10  1   2012-02-07
27  Title of Photo8     2012-07-02  1   23  13  1   2012-02-07
34  Something       2012-07-02  1   14  13  1   2012-02-07
35  Something       2012-03-20  1   37  17  1   2012-03-07
36  Something       2012-03-13  1   38  10  1   2012-03-07

【问题讨论】:

    标签: sql sql-server-2008 tsql join


    【解决方案1】:

    在我看来,您需要更改两件事:AlbumID 上的过滤器应该来自 PhotoMappings,而不是 PhotoDetail,并且您需要在 PhotoDetails 上左连接。

    SELECT d.PhotoTitle,
           m.AlbumID,
           p.PhotoTN AS TN,
           p.PhotoID AS PID,
           p.PhotoLarge AS PL,
           case when d.PhotoId is null 
                then 'NO' 
                else 'YES' 
            end AS [Details]
      FROM Photos p
     INNER JOIN PhotoMappings m
        ON p.PhotoId = m.PhotoId
      LEFT JOIN  PhotoDetails d
        ON p.PhotoId = d.PhotoId
     WHERE m.AlbumID = 14
       and m.LanguageID = 1
    

    【讨论】:

    • @KnowledgeSeeker 请检查我修改后的查询。
    • 它显示了 8 行,其中 1 行来自 AlbumID 10,其他行来自 13 和 YES 在详细信息的所有字段中。虽然它应该完全按照我在部分实际问题中显示的方式显示输出。
    • 我被这个查询数据吓坏了,似乎是正确的,我一定是在某处做错了什么......
    • 我不明白它是怎么回事 - AlbumID 上有一个过滤器,将结果限制为专辑 14。您能否发布这三个表的示例数据?
    • @KnowledgeSeeker 存在两个问题:选择列表中的 d.AlbumID 应为 m.AlbumID,并且可能存在数据错误。照片 19 和 23 在映射中被标记为好像它们属于相册 14,但详细信息表明它们属于相册 10 和 13。如果有意这样做,映射和详细信息之间的连接应扩展为包含 and m.AlbumID = d.AlbumID。见this Sql Fiddle
    【解决方案2】:

    在 PhotoMappings 应该工作之前左外部 JOIN:

    SELECT d.PhotoTitle,d.AlbumID,p.PhotoTN AS TN,  p.PhotoID AS PID,
    p.PhotoLarge AS PL,
    case when d.PhotoId is null then 'NO' else 'YES' end AS [Details]
    FROM Photos p  JOIN  PhotoDetails d
    ON  p.PhotoId = d.PhotoId 
    left outer JOIN PhotoMappings m
    ON  p.PhotoId = m.PhotoId 
    WHERE d.AlbumID  = 14 and m.LanguageID = 1
    

    【讨论】:

    • 我之前尝试过类似的查询,但结果保持不变。我也尝试了您的查询,它只向我显示了前 6 行 desired output,正如我在实际问题的一部分中所显示的那样
    猜你喜欢
    • 2021-01-07
    • 2012-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-28
    • 2023-03-11
    • 1970-01-01
    相关资源
    最近更新 更多