sql - 在同一张表上动态交叉选择查询

标签 sql postgresql

我的访问表格式如下。

ID  access value
1   18      ab
1   32      bc
1   48      cd
2   18      ef
3   18      ab  
3   32      bc

我需要根据输入获取所有有权访问特定号码的 ID。

如果输入是[{access:18,value:ab},{access:32, value:bc}]

select id from access where access = 18 and value ='ab'
intersect
select id from access where access = 32 and value = 'bc'

输出为1,3

如果输入是[{access:18,value:ab},{access:32, value:bc},{access:48,value:cd}]

select id from access where access = 18 and value ='ab'
intersect
select id from access where access = 32 and value ='bc'
intersect
select id from access where access = 48 and value ='cd'

输出为 1。

如何以更好的方式编写上述查询,以便根据输入获得所需的结果。

最佳答案

我认为您将输入作为 json 数组传递。您可以使用 json_to_recordset 将其转换为行,然后与 access 表进行连接并将计数与 HAVING 进行比较以获得交集。

SQL Fiddle

PostgreSQL 9.6 架构设置:

CREATE TABLE access
    (ID int, access int, value varchar(2))
;

INSERT INTO access
    (ID, access, value)
VALUES
    (1, 18, 'ab'),
    (1, 32, 'bc'),
    (1, 48, 'cd'),
    (2, 18, 'ef'),
    (3, 18, 'ab'),
    (3, 32, 'bc')
;

查询 1:

SELECT  ID
FROM access a
INNER JOIN (
    SELECT *, COUNT(*) OVER () as ct
    FROM json_to_recordset('[{"access":18,"value":"ab"},{"access":32, "value":"bc"}
                            ,{"access":48,"value":"cd"}
                            ]'
                          ) 
        AS j("access" INT, "value" TEXT)
    ) j ON (
        j.access = a.access
        AND j.value = a.value
        ) GROUP BY ID HAVING COUNT(*) = MAX(ct)

Results :

| id |
|----|
|  1 |

关于sql - 在同一张表上动态交叉选择查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50077680/

相关文章:

sql - 仅当 SQL 中存在行时返回值

MySQL 查询每月产生的数量

php - 字段列表中的列 'id' 使用 Eloquent 不明确

sql - 甲骨文 PLS-00363 : expression '' cannot be used as an assignment target

postgresql - 跨两个表的排除约束

sql - 编写 PostgreSQl 函数的更好方法

mySQL查询查找两行时间不满足条件的地方

mysql - 调整MySQL排名查询

database - PostgreSQL 在不动态编写 SQL 的情况下执行多个动态 WHERE 条件

sql - PostgreSQL - 检测系列中的模式