繁体   English   中英

如何查询两个值必须匹配的数据

[英]How to query data where 2 values must match

(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子句,则相反。

为什么我的逻辑使我失望?

AND子句之间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' )

您可以使用以下数据透视表:

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聚合函数创建值的集合,并使用SUBMULTISET运算符进行设置比较:

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次表扫描,而以上两个选项中的任何一个都只会进行一次表扫描。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM