2017-02-15 42 views
0

(Oracle 11g)如何查询2值必须匹配的数据

我有一个返回的查询。

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

您可以使用数据透视表:

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次表扫描,而任一的上述选项将仅做一个单一表扫描。

+0

OK ty。让我玩这个一些。我的声明是我的where子句中“AND”声明的一部分。我还有其他的过滤功能,我省略了这个问题。 – PrivateJoker

+0

@JDS使用'COLLECT'解析函数(而不是聚集),这应该让你输出在相同的结构中的数据在另一个替代增补 – MT0

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') 
+0

OR语句给我一个或另一个。我只想要一个结果,当AAA和BBB匹配给定的OrderID – PrivateJoker