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

Posted

技术标签:

【中文标题】PL SQL 查询以查找与列表中的所有值匹配的标识符列表【英文标题】:PL SQL query to find a list of identifiers that matches all values in a list 【发布时间】:2018-12-01 22:13:53 【问题描述】:

假设我有一个包含以下数据的表:

SHELF_ID    PRODUCT_ID

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

我做了一个从另一个表返回的查询“queryA”

PRODUCT_ID

product1
product2

现在我想在另一个查询中使用“queryA”来确定哪些货架至少包含“queryA”中返回的所有产品

通过查看第一个表,您很容易意识到它的架子 1 和架子 2,但是如何在 PL SQL 中实现呢?

谢谢

【问题讨论】:

您是真的指PL/SQL,还是指Oracle SQL(甚至不知道PL/SQL 是什么意思)?您提到查询,这表明您使用的是 Oracle SQL,而不是 PL/SQL。 【参考方案1】:

我认为这个查询可以帮助你找到你想要的:

基本上我做了什么: 首先,我对每个货架的 product_id 做了COUNT(DISTINCT ),然后检查这个计数是否等于或大于 queryA 产品列表,这意味着货架产品匹配。 然后,如果产品与使用 EXISTS() 的 queryA 不匹配,我会排除它们。如果您还想查看不匹配的产品,则无需使用该过滤器。

--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
            )

【讨论】:

@N.Car 。 . .您正在接受一个完全没有必要使用中间表的答案。 @GordonLinoff 。我准备了展示货架和相关产品的清单。如果我不想看到产品,我会使用您的查询。【参考方案2】:

你可以这样做:

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);

基本上,这会计算每个货架上的匹配数,并确保匹配数是产品的总数。

如果shelves 中没有重复项,则可以使用having count(*) = . . .)

【讨论】:

谢谢!我不知道“HAVING”子句将是这里的关键。将另一个回复标记为已接受答案,因为他在几秒钟前回复了。点赞!【参考方案3】:

您可以这样做 - 无需聚合。 (除了顶部查询中的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
                                     )
                  )
;

【讨论】:

以上是关于PL SQL 查询以查找与列表中的所有值匹配的标识符列表的主要内容,如果未能解决你的问题,请参考以下文章

两个表查询(SQL 和 ColdFusion)中的匹配值

Mongo 查询以查找任何字段元素与任何查询参数元素匹配的文档

WPF比较两个数据表以查找匹配值

pl/sql 查询以通过 deptno 查找经理名称

SQL 查询以查找遵循特定模式的字符串

查询匹配列表 SQL Server 中的所有记录