【问题标题】:Using Listagg to get only one row when joining data from 4 tables连接4个表的数据时使用Listagg只获取一行
【发布时间】:2015-11-06 11:01:26
【问题描述】:

我在 4 个表中有数据,并希望在一行中有以下数据: 表1.*,表2.*,表3.*,表4.*

我正在使用内部连接来执行此操作,但 table4 有 2 行具有相同的外键,所以我得到了两行而不是一行。我想使用 Listagg 来解决这个问题并将两个记录合并为一个,但我不确定如何做到这一点。我只看到您选择特定列的示例,而不是 *。

【问题讨论】:

  • 你查看listagg标签信息了吗?我已经给出了文档的链接以及示例的用法。
  • 请以表格形式向我们展示您的预期输入和预期结果。

标签: sql oracle oracle11g listagg


【解决方案1】:

您还没有看到使用* 的示例,因为您不能这样做,至少对于包含您要聚合的列的表来说是这样。您不想按要聚合的列进行分组,因为默认值是目的。无法从 * 列表中排除列,因此如果您这样做了,请说:

select t4.*, listagg(col2) within group (order by col2)
from t4
group by t4.col1;

然后你会得到“ORA-00979: not a GROUP BY expression”,因为col2 不在 group-by 中;如果您包含它,那么无论如何您都会为col2 的每个唯一值返回一行,而不是值列表。

你必须展开列列表:

select t4.col1, listagg(t4.col2) within group (order by t4.col2)
from t4
group by t4.col1;

可以仍将t1.* 等用于您的连接版本,但因为无论如何您都必须在 group-by 子句中明确列出所有表中的所有列(* 是'不允许在那里,只在选择列表中)它并没有真正让你受益:

select t1.*, t2.*, t3.*, t4.col1,
  listagg(t4.col2) within group (order by t4.col2)
from t1
join ... 
group by t1.col1, t1.col2, t2.col1, ..., t4.col1;

你也可以这样做:

select t1.col1, t1.col2, t2.col1, ..., t4.col1,
  listagg(t4.col2) within group (order by t4.col2)
from t1
join ... 
group by t1.col1, t1.col2, t2.col1, ..., t4.col1;

通常更好的做法是在选择列表中明确列出所有列,以避免意外 - 如果列在不同环境中的表中的顺序不同,您将不会看到问题(这不应该真的在适当的源代码控制下无论如何都会发生)并且如果将列添加到表中,查询结果将不会改变。 select * 对于即席查询很有用,但实际上不应该在实际代码中使用。

【讨论】:

  • 好的,我理解您的担忧。但我正在构建这个查询只是为了将一些数据导出到 CSV 以用于进一步处理,并且有很多列,所以我真的试图避免全部输入它们。我目前最后没有 GROUP BY,也许我不需要它。我的查询目前看起来像这样:SELECT LISTAGG(agg_column, ',') WITHIN GROUP (ORDER BY agg_column) FROM( SELECT DISTINCT t1.*,t2.*,t3.*,t4.agg_column from t1 INNER JOIN t2 ON .. . INNER JOIN t3 ON ... INNER JOIN t4 ON ... WHERE xxxx)。如果我将开头修改为 SELECT *,LISTAGG(agg_column, ',')... 当然它不起作用
  • 但我需要在结果中包含所有列,而不仅仅是 agg_column
  • @Tians - 但你不想要所有的列;你想要所有这些除了 agg_column。如果您包含任何非聚合列(您想要这样做),那么您必须有一个group by 子句,还包括除agg_column 之外的所有列。 (或者您可以使用分析版本,但是您必须改为按所有这些进行分区)。您必须全部输入。或者你可以从数据字典中生成它们,但这似乎比它的价值更麻烦。
  • 好吧,你是对的,除了把它们都写出来,大概没有别的办法了。
  • @Tians - 如果您只是想避免将它们全部输入和拼写错误,您可以get them from the data dictionary,正如我之前所说的;然后只需将其复制并粘贴到您的真实查询中。
猜你喜欢
  • 2013-11-11
  • 1970-01-01
  • 2018-10-17
  • 2023-04-04
  • 2016-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
相关资源
最近更新 更多