2

我有一张我必须使用的桌子,不幸的是它的设计不是很好。该表列出了与其他产品匹配的现有产品。有两种类型的匹配:与主要类别产品的匹配和与替代类别产品的匹配。

只要有匹配项,该匹配项的 ID 就会填充到表的相关列中,如下面的 PRODUCT_MATCH 中所示。因此,在每个产品行中,将在 PRODUCT_MAIN_CATEGORY_ID 或 PRODUCT_ALTERNATIVE_CATEGORY_ID 中指定一个 PRODUCT_ID,但不会同时指定两者。

产品

PRODUCT_ID  PRODUCT_CATEGORY PRODUCT_SERIAL_NO
1001        Book             XSDAD132   
1002        MP3              X348023948
1003        DVD              5234234023948
2003        CD               SDRX83489
2002        Video            23423879JJ0

PRODUCT_MATCH

PRODUCT_MATCH_ID, PRODUCT_ID, MAIN_CATEGORY_ID, ALTERNATIVE_CATEGORY_ID, PRODUCT_CATEGORY
1         1001      1002                        Book
2         1001                  1003            Book
3         1002      1004                        Book
4         2002                  1002            Video
5         2002      1003                        Video
6         2002      1001                        Video       
7         2002      1002                        Video       
8         1003                  2003            DVD    

我必须阅读 PRODUCT_MATCH 表,以便如果在 MAIN_CATEGORY_ID 上匹配我显示 ID,或者如果有 ALTERNATIVE_CATEGORY_ID 我必须显示 product_id 和产品 ID 的序列号。

我编写了以下查询来显示结果

select product_id,
cast(collect(coalesce(MAIN_CATEGORY_ID,
  decode(ALTERNATIVE_CATEGORY_ID,null,null, ALTERNATIVE_CATEGORY_ID || '-' || PRODUCT_CATEGORY))) as myType) as product_matches
from product_match
group by product_id

注意:MyType 定义为 varchar(2000) 的表

如果 MAIN_CATEGORY_ID 不为空,则查询将使用 MAIN_CATEGORY_ID,否则将使用 ALTERNATIVE_CATEGORY_ID 中的值来构建输出。我想更改它,以便每当合并函数使用 ALTENATIVE_CATEGORY_ID 值时,它都会显示与 PRODUCT 编号中的 product_serial_no 连接的 product_id。这将需要与 PRODUCT 表连接。

基本上我想要实现的输出如下所示:

PRODUCT_ID  PRODUCT_MATCHES
-----------------------------------
1001        1002,DVD-5234234023948
1002        1004
2002        MP3-X348023948, 1003, 1001, 1002
1003        CD-SDRX83489

我知道我可以简单地加入表格,但它不是那么简单。问题是我只想在使用 ALTERNATIVE_CATEGORY_ID 时使用连接。这意味着一个简单的连接将影响使用 MAIN_CATEGORY_ID 时的结果。

4

2 回答 2

4
select 
   pm.product_id, 
   cast(
      collect(
         coalesce(
            pm.MAIN_CATEGORY_ID, 
            pm.ALTERNATIVE_CATEGORY_ID || '-' || pr.PRODUCT_SERIAL_NO
         )
      ) as myType
   ) as product_matches
from 
   product_match pm
   left join PRODUCT pr
      on pr.PRODUCT_ID = pm.ALTERNATIVE_CATEGORY_ID
group by 
   pm.product_id
于 2013-02-23T15:45:21.813 回答
1

我认为 LISTAGG() 或 WM_CONCAT() 函数是你正在寻找的,因为你写的是你有表而不是嵌套表或集合。Collect 将返回一个集合,主要用于 PL/SQL 数据类型而不是简单表。LISTAGG() 或 WM_CONCAT() 会将值连接成一个字符串,与您的示例完全相同。抱歉,我不会添加任何查询,因为您的输出让我非常困惑。我只看到与 product_id = 1001 匹配的图书,而不是 DVD 和其他内容。如果您使用 SQL Fiddle 创建示例数据或简单地创建表并插入,那就太好了。请在将来这样做。

这对我有用 - emp_test 是 scott.emp 表的精确副本:

ALTERE TABLE emp_test MODIFY ename VARCHAR2(3000);

Update emp_test set ename = rpad(ename, 3000, ' '); Commit;

SELECT deptno
     , LISTAGG(TRIM(SUBSTR(ename, 1, 3000)), ',') WITHIN GROUP (ORDER BY ename) AS employees
    , count(*) total_emps
  FROM emp_test
GROUP BY deptno
/

SELECT deptno
     , WM_CONCAT(TRIM(SUBSTR(ename, 1, 3000))) AS employees
     , count(*) total_emps
 FROM emp_test
GROUP BY deptno
/
于 2013-02-27T15:03:36.550 回答