【问题标题】:select single row of multiple records in One to Many relation tables在一对多关系表中选择多条记录的单行
【发布时间】:2018-09-18 11:08:19
【问题描述】:

在 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 语句时,我无法检索空记录。我该如何解决这个问题?

【问题讨论】:

  • 只获取接下来的 1 行
  • 我已经有了。 @Mazhar
  • 你是否故意用fetch next 1将结果限制为1行?
  • 是的。带有图像的产品。同一类别中每个 productID 的单个记录。 Images 表可以有同一个 productID 的多个 imagePaths,或者没有记录。我将多条记录限制为 1。如果图像表中没有 ProductID 的记录,则将 ImagePaths 显示为 NULL。左外在这样做。但是使用 fetch,不会出现空记录。 @DmitryPolyakov

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


【解决方案1】:

根据您的评论,我认为您误解了 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

【讨论】:

    【解决方案2】:
    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 名返回的结果与我的相同。忽略空记录。
    【解决方案3】:

    试试这个代码,productImage 是最大的。每个产品 ID 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 2011-01-07
      • 2018-09-27
      • 2011-12-30
      • 2017-08-20
      相关资源
      最近更新 更多