在一对多关系表中选择多个记录的单行

时间:2018-09-18 11:08:19

标签: sql sql-server left-join one-to-many offset

在MSSQL中,我有两个具有一对多关系的表。

表格:

tb_Products:
ID
ProductName

tb_Images:
ProductID
MidPath

在存储过程中,显示​​带有图像的产品(还显示空记录), 而且,如果tb_Images中有多个productID,则会显示一条记录。

我可以通过以下查询来完成这项工作:

declare @rowIndexToFetch int
set @rowIndexToFetch=0

select p.ID,p.ProductName,p.CategoryID,c.ParentId,  
    pi.MidPath
    from tb_Products p
    join tb_Categories c
    on p.CategoryID=c.ID
    left outer join tb_Images pi
    on pi.ProductID=p.ID

    where c.ID=3 or c.ParentId=3

    order by pi.ID desc
    offset @rowIndexToFetch rows
    fetch next 1 rows only

但是,如果我使用offset和fetch,我将无法再从tb_Images中检索NULL记录。左外部联接不再起作用。

不带偏移量获取的示例记录返回:

ID    ProductName   CategoryID   ParentId  MidPath
154   Chef Ceket     33            3       /cdn/www.sample.com/x
154   Chef Ceket     33            3       /cdn/www.sample.com/y
154   Chef Ceket     33            3       /cdn/www.sample.com/z
1     Eldiven        3             3       NULL

通过偏移量获取:

ID    ProductName   CategoryID   ParentId  MidPath
154   Chef Ceket     33            3       /cdn/www.sample.com/x

预期返回:

   ID    ProductName   CategoryID   ParentId  MidPath
   154   Chef Ceket     33            3       /cdn/www.sample.com/x
   1     Eldiven        3             3       NULL

问题是,当我使用offset-fetch语句时,无法检索空记录。我该如何解决?

3 个答案:

答案 0 :(得分:0)

select distinct p.ID,p.ProductName,p.CategoryID,c.ParentId,  
    pi.MidPath
    from tb_Products p
    join tb_Categories c
    on p.CategoryID=c.ID
    left outer join tb_Images pi
    on pi.ProductID=p.ID

    where c.ID=3 or c.ParentId=3
        where c.ID=3 or c.ParentId=3

答案 1 :(得分:0)

尝试此代码,在productImage中最大。每个productID 1个值。

WITH    productImage
      AS ( SELECT   MAX(pi.ID) AS ID
                  , pi.ProductID
           FROM     tb_Images pi
           GROUP BY pi.ProductID
         )
SELECT  p.ID
      , p.ProductName
      , p.CategoryID
      , c.ParentId
      , pi.MidPath
FROM    tb_Products p
        JOIN tb_Categories c ON p.CategoryID = c.ID
        LEFT OUTER JOIN productImage ON productImage.ProductID = p.ID
        LEFT OUTER JOIN tb_Images pi ON pi.ID = productImage.ID
WHERE   c.ID = 3
        OR c.ParentId = 3;

答案 2 :(得分:0)

根据您的评论,我认为您误解了OFFSET FETCH构造的行为。再看看手册。

如果要获得上述结果,可以使用此类查询

WITH query AS (
    SELECT 
        p.ID,
        p.ProductName,
        p.CategoryID,
        c.ParentId,  
        pi.MidPath,
        rn = ROW_NUMBER() OVER( PARTITION BY p.ID ORDER BY pi.MidPath )-- in your code ORDER set by pi.ID but there's no evidence it exists
    FROM tb_Products p
    JOIN tb_Categories c ON p.CategoryID = c.ID
    LEFT JOIN tb_Images pi ON pi.ProductID = p.ID
    WHERE c.ID = 3 or c.ParentId = 3
)
SELECT ID, ProductName, CategoryID, ParentId, MidPath
FROM query
WHERE rn = 1