【问题标题】:How to use wm_concat one a column that already exists in the query?如何使用 wm_concat 一个查询中已经存在的列?
【发布时间】:2021-10-04 01:39:04
【问题描述】:

所以...我目前使用的是 Oracle 11.1g,我需要创建一个查询,该查询使用来自 Table_with_value 的 ID 和 CusCODE,并使用 ID 检查 Table_with_status 以查找活动的 CO_status 但在不同的 CusCODE 上。

这是我目前所拥有的 - 除非手动提供 CusCODE 和 ID,否则显然不能正常工作:

SELECT wm_concat(CoID) as active_CO_Status_for_same_ID_but_different_CusCODE
FROM Table_with_status
WHERE 
CoID IN (SELECT CoID FROM Table_with_status WHERE ID = Table_with_value.ID AND CusCODE != Table_with_value.CusCODE)) AND Co_status = 'active';

Table_with_value:

|CoID | CusCODE | ID | Value |
|--------|---------|----------|----|
|354223 | 1.432 | 0784296L | 99 |
|321232 | 4.212321.22 | 0432296L | 32 |
|938421 | 3.213 | 0021321L | 93 |

Table_with_status:

|CoID | CusCODE | ID | Co_status|
|--------|--------------|----------|--------|
|354223 | 1.432 | 0784296L | active|
|354232 | 1.432 | 0784296L | inactive |
|666698 | 1.47621 | 0784296L | active |
|666700 | 1.5217 | 0784296L | active |
|938421 | 3.213 | 0021321L | active |
|938422 | 3.213 | 0021321L | active |
|938423 | 3.213 | 0021321L | active |
|321232 | 4.212321.22 | 0432296L | active |
|321232 | 4.212321.22 | 0432296L | active |
|321232 | 1.689 | 0432296L | inactive |

预期输出:

|CoID | active_CO_Status_for_same_ID_but_different_CusCODE  | ID | Value |
|--------|---------|----------|----|
|354223 | 666698,666700 | 1.432 | 0784296L | 99 |
|321232 | N/A | 4.212321.22 | 0432296L | 32 |
|938421 | N/A | 3.213 | 0021321L | 93 |

关于如何在没有任何 PL/SQL for 循环的情况下理想地实现这一点的任何想法,但它也应该没问题,因为预计输出数据集

对于我提出问题的含糊性质,我提前道歉 :) 如果有不清楚的地方,请告诉我。

【问题讨论】:

  • “显然不起作用” - 为什么很明显;你现在得到什么结果?你也许只需要group by ID, CusCodeCoId, Value 可能是预期的输出(并在选择列表中包含相关列)?
  • 在选择列表中添加 wm_concat(Table_with_status.CoID) 和 Table_with_value.CoID 是我真正需要帮助的 - 我构造查询的方式是不允许的。

标签: sql oracle11g string-aggregation


【解决方案1】:

从您的描述和预期输出来看,您似乎需要一个左外连接,例如:

SELECT v.CoID,
  wm_concat(s.CoID) as other_active_CusCODE -- active_CO_Status_for_same_ID_but_different_CusCODE
  v.CusCODE,
  v.ID,
  v.value
FROM Table_with_value v
LEFT JOIN Table_with_status s
ON s.ID = v.ID
AND s.CusCODE != v.CusCODE
AND s.Co_status = 'active'
GROUP BY v.CoID, v.CusCODE, v.ID, v.value;

SQL Fiddle 使用 listagg() 而不是从不支持且现已删除的 wm_concat();如果逻辑不是我解释的那样,可以使用几种不同的方法。有了你的样本数据,他们都得到了:

COID   OTHER_ACTIVE_CUSCODE CUSCODE     ID       VALUE
------ -------------------- ----------- -------- -----
321232 (null)               4.212321.22 0432296L    32
354223 666698,666700        1.432       0784296L    99
938421 (null)               3.213       0021321L    93

【讨论】:

  • 做到了。非常感谢亚历克斯。不幸的是,listagg() 在 Oracle 11.1g 中不可用,所以 wm_concat() 必须这样做。
  • 是的,我注意到你说你在 11.1 - 我不得不使用 listagg() 作为小提琴,但在答案中留下了 wm_concat() *8-)
【解决方案2】:

假设您引用了正确的表,您的代码看起来应该可以工作:

SELECT wm_concat(s.CoID) as active_CO_Status_for_same_ID_but_different_CusCODE
FROM Table_with_status s
WHERE s.CoID IN (SELECT v.CoID
                 FROM Table_with_value v
                 WHERE v.ID = s.ID AND
                       v.CusCODE <> s.CusCODE
                ) AND
      s.Co_status = 'active';

【讨论】:

  • 是的,确实如此。也许我没有很好地表达它,但我如何添加 v.Co_ID 和 wm_concat(s.CoID) 以显示为单独的列?
  • @MatthewZammit 。 . .在这种情况下,亚历克斯的答案应该做你想做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-10
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
相关资源
最近更新 更多