如何在查询中使用数组参数使用 AND 条件
How can I use AND condition using array parameter in a query
我有一个具有多个参数的oracle查询,其中一个参数就像一个数组,参数名称例如:COLOR。假设我有 table 个人
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
32 Mark blue
45 Bob red
25 Lean white
01 Sara Orange
我想在两个不同的查询中以两种方式使用此参数,一种使用 OR 条件,另一种使用 AND 条件。假设我想要所有 "Red OR blue" 的名字
如果我将参数发送到 :COLORS 为
|red|blue|
并编写此查询
SELECT ID, NAME, COLOR
FROM PEOPLE
WHERE INSTR(:COLORS, COLORS) > 0
GROUP ID, NAME, COLOR;
结果会是这样的:
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
32 Mark blue
45 Bob red
这很好,但我的问题是:如何将它用作 AND 条件?
就像如果我想要所有具有 "Red AND blue" 的名字,这意味着结果应该是这样的:
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
有人可以帮我解决这个问题吗?
要查找人员,您可以:
SELECT ID, NAME
FROM PEOPLE
WHERE INSTR(:COLORS, WARECOLOR) > 0
GROUP ID, NAME
HAVING COUNT(*) = regexp_count(:COLORS,'[|]') - 1 ;
regexp_count(:COLORS,'[|]')
只计算来自 :COLORS 的 |
。
如果您的 table 没有正确规范化(您有重复项),您可以使用 count(distinct WARECOLOR)
而不是 count(*)
那么获取行就简单了:
SELECT ID, NAME, COLOR
FROM PEOPLE
WHERE id, name in (
SELECT ID, NAME
FROM PEOPLE
WHERE INSTR(:COLORS, WARECOLOR) > 0
GROUP ID, NAME
HAVING COUNT(*) = regexp_count(:COLORS,'[|]') - 1 ;
)
;
您可以在 SQL 服务器 开发环境中尝试以下 SQL 脚本。
我使用用户定义函数 dbo.split() 到 split input string using SQL
/*create table colorTbl (
ID int, NAME varchar(10), WARECOLOR varchar(10)
)
insert into colorTbl select 12,'Sabrina','red'
insert into colorTbl select 12 ,'Sabrina','blue'
insert into colorTbl select 32 ,'Mark','blue'
insert into colorTbl select 45 ,'Bob','red'
insert into colorTbl select 25 ,'Lean','white'
insert into colorTbl select 01 ,'Sara','Orange'*/
declare @color varchar(max) = '|red|blue|'
;with cte as (
select val, COUNT(*) over (partition by 1) cnt1
from dbo.Split(@color,'|')
where val <> ''
)
select *
from (
select *, COUNT(*) over (partition by name) cnt2
from colorTbl c
inner join cte on c.warecolor = cte.val
) t where cnt1 = cnt2
拆分功能returns颜色和每种颜色的订单号。
这使您能够知道输入参数的计数。
使用 SQL Count() function with Partition By 子句使我能够计算颜色与每个用户匹配的行。
当我匹配这两个计数值时,您将为连接的参数值实现 AND。
我有一个具有多个参数的oracle查询,其中一个参数就像一个数组,参数名称例如:COLOR。假设我有 table 个人
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
32 Mark blue
45 Bob red
25 Lean white
01 Sara Orange
我想在两个不同的查询中以两种方式使用此参数,一种使用 OR 条件,另一种使用 AND 条件。假设我想要所有 "Red OR blue" 的名字 如果我将参数发送到 :COLORS 为
|red|blue|
并编写此查询
SELECT ID, NAME, COLOR
FROM PEOPLE
WHERE INSTR(:COLORS, COLORS) > 0
GROUP ID, NAME, COLOR;
结果会是这样的:
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
32 Mark blue
45 Bob red
这很好,但我的问题是:如何将它用作 AND 条件? 就像如果我想要所有具有 "Red AND blue" 的名字,这意味着结果应该是这样的:
ID NAME WARECOLOR
12 Sabrina red
12 Sabrina blue
有人可以帮我解决这个问题吗?
要查找人员,您可以:
SELECT ID, NAME
FROM PEOPLE
WHERE INSTR(:COLORS, WARECOLOR) > 0
GROUP ID, NAME
HAVING COUNT(*) = regexp_count(:COLORS,'[|]') - 1 ;
regexp_count(:COLORS,'[|]')
只计算来自 :COLORS 的 |
。
如果您的 table 没有正确规范化(您有重复项),您可以使用 count(distinct WARECOLOR)
而不是 count(*)
那么获取行就简单了:
SELECT ID, NAME, COLOR
FROM PEOPLE
WHERE id, name in (
SELECT ID, NAME
FROM PEOPLE
WHERE INSTR(:COLORS, WARECOLOR) > 0
GROUP ID, NAME
HAVING COUNT(*) = regexp_count(:COLORS,'[|]') - 1 ;
)
;
您可以在 SQL 服务器 开发环境中尝试以下 SQL 脚本。 我使用用户定义函数 dbo.split() 到 split input string using SQL
/*create table colorTbl (
ID int, NAME varchar(10), WARECOLOR varchar(10)
)
insert into colorTbl select 12,'Sabrina','red'
insert into colorTbl select 12 ,'Sabrina','blue'
insert into colorTbl select 32 ,'Mark','blue'
insert into colorTbl select 45 ,'Bob','red'
insert into colorTbl select 25 ,'Lean','white'
insert into colorTbl select 01 ,'Sara','Orange'*/
declare @color varchar(max) = '|red|blue|'
;with cte as (
select val, COUNT(*) over (partition by 1) cnt1
from dbo.Split(@color,'|')
where val <> ''
)
select *
from (
select *, COUNT(*) over (partition by name) cnt2
from colorTbl c
inner join cte on c.warecolor = cte.val
) t where cnt1 = cnt2
拆分功能returns颜色和每种颜色的订单号。 这使您能够知道输入参数的计数。 使用 SQL Count() function with Partition By 子句使我能够计算颜色与每个用户匹配的行。 当我匹配这两个计数值时,您将为连接的参数值实现 AND。