【问题标题】:Retrieving a list of rows with only a single item from other table in Oracle从Oracle中的其他表中检索只有一个项目的行列表
【发布时间】:2013-01-22 14:50:11
【问题描述】:

我在Oracle数据库中有两张表(10g express)

  • 产品
  • product_image

一个产品可以有多个图像。因此,productproduct_image 之间存在一对多关系,product_image 表有一个外键引用 product 表的主键。

我需要获取一个产品列表,在要检索的结果集的每一行中只有一个图像名称,而不管product_image中的图像如何表(即使某些产品没有图片)。

要从product_image 表中检索的图像名称​​一般是在对每个产品的每组图像进行排序后,product_image 表中的第一个图像名称按升序排列。类似于以下内容。

prod_id    prod_name    prod_image

      1    aaa          aaa.jpg      //The first image name in the product_image table after sorting images for prod_id in ascending order.
      2    bbb          bbb.jpg      //Similar to the first case.
      3    ccc            -          //No image(s) found in the product_image table 
      4    ddd            -          //Similar to the previous case.

这两个表的一般连接语句类似于以下内容。

SELECT p.prod_id, p.prod_name, pi.prod_image 
FROM product p 
INNER JOIN product_image pi 
ON p.prod_id=pi.prod_id;

这可以使用单个 SQL 语句吗?

【问题讨论】:

    标签: oracle oracle10g greatest-n-per-group


    【解决方案1】:

    如果我正确理解了您的问题,我认为以下查询会起作用。我没有测试过。

    SELECT p.prod_id, p.prod_name, MIN(DBMS_LOB.substr(pi.prod_image, 1))
    FROM product p LEFT JOIN product_image pi 
    ON p.prod_id=pi.prod_id 
    GROUP BY p.prod_id, p.prod_name
    ORDER BY p.prod_name;
    

    【讨论】:

    • Oracle 回复 - ORA-00932: inconsistent datatypes: expected - got CLOBpi.prod_image 是数据库中的 clob 类型字段。
    • 用 MIN(图像名称字段)替换 MIN(pi.prod_image)
    • 图像名称字段prod_image(在数据库中)。因此,它与您的答案相同MIN(pi.prod_image)
    • 我已经编辑了我的答案。您是否有任何理由使用 CLOB 字段来保存文件名而不是 varchar2?
    【解决方案2】:

    试试这个,您可以为每个 prod_id 的每个图像生成行号并使用它。要从丢失的产品图像中返回 null 或空白,您应该使用左外连接

    WITH CTE AS
    (
    
    SELECT prod_id, DBMS_LOB.substr(prod_image,1,4000) prod_image, 
    row_number() over (partition by prod_id order by prod_image) rn
    FROM product_image
    )
    
    SELECT p.prod_id, p.prod_name, nvl(pi.prod_image,'-') prod_image
    FROM product p 
    LEFT OUTER JOIN CTE pi 
    ON p.prod_id=pi.prod_id and pi.rn = 1;
    

    【讨论】:

    • Oracle 回复 - ORA-32033: unsupported column aliasing。数据库中的列名和表名与您在答案中使用的相似。
    • @Tiny,更新了我的答案,我在CTE 之后输入了错误的AS 关键字
    • 我接受了我自己的答案,只是因为它是通用 SQL。
    【解决方案3】:

    以下 SQL 工作如问题中所述。

    SELECT 
         p.prod_id,
         p.prod_name,
         t.prod_image 
    FROM
         product p 
    LEFT OUTER JOIN(
         SELECT 
               pi.prod_image_id,
               pi.prod_id,
               pi.prod_image 
         FROM
               product_image pi 
         INNER JOIN (
               SELECT 
                    MIN(pi.prod_image_id) AS prod_image_id 
               FROM 
                    product_image pi
               GROUP BY 
                    pi.prod_id
         ) prod_image 
         ON pi.prod_image_id=prod_image.prod_image_id
    )t ON p.prod_id=t.prod_id ORDER BY p.prod_id DESC;
    

    参考:

    【讨论】:

      猜你喜欢
      • 2023-01-17
      • 1970-01-01
      • 1970-01-01
      • 2016-05-18
      • 2019-01-10
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多