我有这样的查询:
select Table1.column1 AS CODE, COUNT(DINSTINCT(Table2.column1 || '|' || Table2.column2)) AS COUNT
FROM Table2
INNER JOIN Table3 ON Table3.referenceColumn = Table2.referenceColumn
INNER JOIN Table1 ON Table1.referenceColumn = Table2.referenceColumn
WHERE
....
AND Table1.column1 <> ''
查询的输出将是这样的,基本上是一个CODE和相应的COUNT,例如:
CODE COUNT
ref002 3
ref003 1
在第一个查询之后,我有一个foreach
,它将对上面的查询结果进行迭代。在foreach
内,针对每个查询结果
上面,我想要获取一些Table3中可用的信息,基本上,我想要每个CODE(Table1.Column1)的Table3.column1中的所有值。因此,在foreach
内,我还有另一个查询来获取每个迭代结果的Table3.column:
select Table3.column1
FROM Table3
INNER JOIN Table3 ON Table3.referenceColumn = Table2.referenceColumn
INNER JOIN Table1 ON Table1.referenceColumn = Table2.referenceColumn
WHERE ....
AND Table1.column1 = (equal to a parameter (Table1.column1) that is available in each foreach iteration)
这样,我可以获取第一个查询的每个Table1.column1(每个CODE)的所有Table3.column1
值。
怀疑
两个查询几乎相同。 foreach
之前的查询和foreach内部的查询之间的唯一区别是在SELECT
部分和WHERE
中,基本上是其中仅具有附加条件的地方。因此,这两个查询在性能和可维护性方面都不太好,因为两个查询几乎相同。因此,应该有可能在第一个查询中获得所有必要的信息,而不是在foreach
内进行第二个查询。
您知道在第一个查询中需要进行哪些更改,除了返回CODE和COUNT之外,还为每个CODE返回Table3.column1中的所有值?这样就可以删除foreach内部的查询,并获得仅一个查询(第一个查询)所需的所有内容?第一个查询的必要输出应类似于:
CODE COUNT IDNUMBERS
ref002 3 ab00, cd00
ref003 1 ef00
答案 0 :(得分:3)
您的策略为每个代码生成一个查询,再为初始查询生成一个查询,因此确实效率低下。
一个简单的选择是在原始查询中使用字符串聚合函数来生成附加列。
在Oracle中,您可以为此使用listagg()
:
select
t1.column1 as code,
count(distinct t2.column1 || '|' || t2.column2) as cnt,
listagg(t3.column1) idnumbers
from table2 t2
inner join table3 t3 on t3.referencecolumn = t2.referencecolumn
inner join table1 t1 on t1.referencecolumn = t1.referencecolumn
where ...
group by t1.column1
listagg()
具有用于格式化,重复管理和排序的各种选项-您可以找到详细信息in the documentation。