(Oracle 11g)
我有一个返回的查询。
OrderNo MyCode Value
1234 AAA 11
1234 BBB PPP
4732 AAA 11
5555 BBB PPP
我的部分规则只是将结果拉回到AAA和BBB值匹配的OrderNo。 (即我知道进入AAA应该是111而BBB应该是PPP)。
所以从上面的例子中我只应该返回OrderNo 1234
我正在努力设置查询以满足此条件。
目前我在where子句中有以下代码:
AND (
-- Match AAA and BBB values.
AJO.VALUE IN (SELECT VALUE FROM SOME_TABLE WHERE S_FILTER IN (SELECT * FROM TABLE(listFilters)) AND AJO.O_FILTER = 'AAA' )
AND
AJO.VALUE IN (SELECT VALUE FROM SOME_TABLE WHERE S_FILTER IN (SELECT * FROM TABLE(listFilters)) AND AJO.O_FILTER = 'BBB' )
)
如果我注释掉第一部分,我会得到所有匹配的BBB值的结果,反之亦然,如果我注释掉BBB条款。
为什么我的逻辑失败了?
答案 0 :(得分:0)
AND
子句之间的结果为空集(因为它不能同时为AJO.O_FILTER = 'AAA'
和AJO.O_FILTER = 'BBB'
)。您需要OR
:
AJO.VALUE IN (SELECT VALUE FROM SOME_TABLE WHERE S_FILTER IN (SELECT * FROM TABLE(listFilters)) AND AJO.O_FILTER = 'AAA' )
OR
AJO.VALUE IN (SELECT VALUE FROM SOME_TABLE WHERE S_FILTER IN (SELECT * FROM TABLE(listFilters)) AND AJO.O_FILTER = 'BBB' )
答案 1 :(得分:0)
您可以使用以下方式转动表格:
SELECT *
FROM your_table
PIVOT ( MAX( value ) FOR mycode IN ( 'AAA' AS AAA, 'BBB' AS BBB )
这将给出:
ORDERNO AAA BBB
------- --- ---
1234 11 PPP
4732 11
5555 PPP
然后你可以这样做:
SELECT *
FROM (
SELECT *
FROM your_table
PIVOT ( MAX( value ) FOR mycode IN ( 'AAA' AS AAA, 'BBB' AS BBB )
)
WHERE AAA MEMBER OF listFilters
AND BBB MEMBER OF listFilters;
这将给出:
ORDERNO AAA BBB
------- --- ---
1234 11 PPP
<强>替代强>:
您还可以使用COLLECT
aggregation function创建值的集合,并使用SUBMULTISET
operator进行集合比较:
SELECT OrderNo
FROM (
SELECT OrderNo,
CAST( COLLECT( value ) AS your_listFilter_Type ) AS vals
FROM your_table
WHERE myCode IN ( 'AAA', 'BBB' )
GROUP BY OrderNo
)
WHERE listFilters SUBMULTISET OF vals;
备选方案2 :
SELECT orderno, mycode, value
FROM (
SELECT t.*,
CAST(
COLLECT(
CASE WHEN mycode IN ( 'AAA', 'BBB' ) THEN value END
) OVER ( PARTITION BY OrderNo )
AS your_listFilter_type
) AS vals
FROM your_table t
)
WHERE 1 = 1 -- Some conditions
AND listFilters SUBMULTISET OF vals
AND 2 = 2; -- Some more conditions
为什么我的逻辑失败了?
您并不是要限制子查询与外部查询具有相同的OrderNo
。
SELECT *
FROM your_table t
WHERE EXISTS( SELECT 1
FROM your_table x
WHERE x.orderno = t.orderno
AND x.mycode = 'AAA'
AND x.value MEMBER OF listFilters )
AND EXISTS( SELECT 1
FROM your_table x
WHERE x.orderno = t.orderno
AND x.mycode = 'BBB'
AND x.value MEMBER OF listFilters );
然而,这可能会进行3次表格扫描,而上述任何一种选项只会进行一次表扫描。