简体   繁体   English

PL SQL查询以查找与列表中的所有值匹配的标识符列表

[英]PL SQL query to find a list of identifiers that matches all values in a list

Let's assume I have a table that has the following data: 假设我有一个包含以下数据的表:

SHELF_ID    PRODUCT_ID

shelf1      product1
shelf1      product2
shelf1      product3
shelf2      product1
shelf2      product2
shelf3      product1

I made a query 'queryA' that returns from another table 我做了一个查询'queryA'从另一个表返回

PRODUCT_ID

product1
product2

Now I want to use the 'queryA' in another query to identify which shelfs have at least all the products returned in 'queryA' 现在,我想在另一个查询中使用“ queryA”来确定哪些货架上至少具有“ queryA”中返回的所有产品

by looking at the first table you easily realize its shelf1 and shelf2, but how do I make this in PL SQL? 通过查看第一个表,您可以轻松地实现其架子1和架子2,但是如何在PL SQL中实现呢?

Thank you 谢谢

I think this query can help you to find what you want : 我认为此查询可以帮助您找到所需的内容:

Basically what did I do : First I did COUNT(DISTINCT ) to product_id for each shelf and then checked if this count equal or greater than queryA product list that's mean the shelf products match. 基本上,我该怎么做:首先,我对每个货架的product_id执行COUNT(DISTINCT ) ,然后检查此计数是否等于或大于queryA表示货架产品匹配的产品列表。 Then I excluded products if they don't match with queryA with using EXISTS() . 然后,如果我使用EXISTS()将产品与queryA不匹配,则我将其排除在外。 If you want to see also not matched products you don't need to use that filter. 如果您还想查看不匹配的产品,则无需使用该过滤器。

--DROP TABLE shelves;
CREATE TABLE shelves
(
    SHELF_ID    VARCHAR(100)
    ,PRODUCT_ID VARCHAR(100)
);

INSERT INTO shelves
VALUES 
 ('shelf1','product1')
,('shelf1','product2')
,('shelf1','product3')
,('shelf2','product1')
,('shelf2','product2')
,('shelf3','product1');

--DROP TABLE queryA;

CREATE TABLE queryA
(
    PRODUCT_ID  VARCHAR(100)
);

INSERT INTO queryA VALUES ('product1'),('product2');

SELECT  * 
FROM shelves S
WHERE S.SHELF_ID IN (           
                    SELECT S.SHELF_ID
                            --,COUNT(DISTINCT S.PRODUCT_ID) PRODUCTCOUNT
                    FROM shelves S
                    GROUP BY S.SHELF_ID
                    HAVING COUNT(DISTINCT S.PRODUCT_ID)>=(SELECT COUNT(DISTINCT PRODUCT_ID) 
                                                            FROM queryA Q  )        
                    )
AND EXISTS (SELECT 1 
            FROM queryA Q
            WHERE S.PRODUCT_ID = Q.PRODUCT_ID
            )

You can do this as: 您可以这样做:

with products as (
      <your query here)
     )
select s.shelf_id
from shelves s join
     products p
     on s.product_id = p.product_id
group by s.shelf_id
having count(distinct s.product_id) = (select count(*) from products);

Basically, this counts the number of matches on each shelf, and makes sure that the count of matches is the total count of products. 基本上,这会计算每个货架上的火柴数量,并确保火柴数量是产品总数。

If there are no duplicates in shelves , you can use having count(*) = . . .) 如果shelves没有重复项,则可以使用having count(*) = . . .) having count(*) = . . .) having count(*) = . . .) . having count(*) = . . .)

You can do this - no aggregation needed. 您可以执行此操作-无需聚合。 (Other than the SELECT DISTINCT in the top query; it would be MUCH better if you had an additional table, SHELVES , with SHELF_ID as primary key, then the query could be much more efficient.) (除了顶部查询中的SELECT DISTINCT ;如果您有一个附加表SHELVES (以SHELF_ID作为主键,那会更好),那么查询可能会效率更高。)

select distinct shelf_id
from   shelves s
where  not exists (select product_id
                   from   queryA   -- Your existing query goes here
                   where  (s.shelf_id, product_id) 
                              not in (select shelf_id, product_id
                                      from   shelves
                                     )
                  )
;

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

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