嗨我有一个包含两列(WID,DT)和数据的表。
WID DT
-------
A 10
A 11
A 12
B 10
B 11
C 10
C 13
如果我在输入中传递A,B,则输出为10和11.DT的交点。 如果我在输入中传递A,B,C,我应该得到10作为输出。 如果我传递A作为输入,那么10,11,12作为输出.. 我的输入将是动态的取决于UI的一些条件。 如何在查询中实现这一点......
答案 0 :(得分:1)
这是一种不需要为传入的列表中的每个项目添加相交作为参数的方法。我无法保证它在大型数据集上的表现非常好,但是你必须测试你的数据!
第一个示例显示了模拟同时传入的参数的多个值的效果的结果(主要是为了显示您提到的不同测试用例的结果):
with sample_data as (select 'A' WID, 10 DT from dual union all
select 'A' WID, 11 DT from dual union all
select 'A' WID, 12 DT from dual union all
select 'B' WID, 10 DT from dual union all
select 'B' WID, 11 DT from dual union all
select 'C' WID, 10 DT from dual union all
select 'C' WID, 13 DT from dual),
params as (select 'A, B, C' val from dual union all
select 'A, B' val from dual union all
select 'A, C' val from dual union all
select 'B, C' val from dual union all
select 'A' val from dual union all
select 'B' val from dual union all
select 'C' val from dual),
pivot_params as (select val,
trim(regexp_substr(val, '[^,]+', 1, level)) sub_val,
regexp_count(val||',', ',') num_vals
from params
connect by prior val = val
and level <= regexp_count(val||',', ',')
and prior dbms_random.value is not null),
results as (select sd.*,
pp.*,
count(distinct wid) over (partition by pp.val, sd.dt) cnt_of_distinct_wid_per_val
from sample_data sd
inner join pivot_params pp on (sd.wid = pp.sub_val))
select distinct val param,
dt
from results
where num_vals = cnt_of_distinct_wid_per_val
order by 1, 2;
PARAM DT
------- ----------
A 10
A 11
A 12
A, B 10
A, B 11
A, B, C 10
A, C 10
B 10
B 11
B, C 10
C 10
C 13
第二个例子更接近你需要传递一个带有单个值的参数 - 你显然不需要sample_data子查询(你只需使用你的tablename来代替sample_data的使用位置)主查询),你必须用你在代码中使用的参数名替换:param,但希望你能看到你需要修改的内容才能让你的代码工作:
with sample_data as (select 'A' WID, 10 DT from dual union all
select 'A' WID, 11 DT from dual union all
select 'A' WID, 12 DT from dual union all
select 'B' WID, 10 DT from dual union all
select 'B' WID, 11 DT from dual union all
select 'C' WID, 10 DT from dual union all
select 'C' WID, 13 DT from dual),
-- end of mimicking your data
pivot_param as (select :param val,
trim(regexp_substr(:param, '[^,]+', 1, level)) sub_val,
regexp_count(:param||',', ',') num_vals
from dual
connect by level <= regexp_count(:param||',', ',')),
results as (select sd.*,
pp.*,
count(distinct wid) over (partition by pp.val, sd.dt) cnt_of_distinct_wid_per_val
from sample_data sd
inner join pivot_param pp on (sd.wid = pp.sub_val))
select distinct val param,
dt
from results
where num_vals = cnt_of_distinct_wid_per_val
order by 1, 2;
ETA:它的工作方式是:首先,将list-as-a-parameter转换为虚拟表,列表中每个项目一行,以及传入的项目数。(NB我没有考虑你在我的查询中两次输入相同项目的情况 - 你必须修改你在pivot_params子查询中识别项目计数的方式(可能使用count(distinct(...) over (...)
)并确保输出是不同的。)
将参数列表转换为表后,可以将其加入包含数据的表(在上面的查询中,即sample_data子查询),并找出每个DT有多少个唯一的WID 。如果计数与参数列表中的项目数相同,那么您就知道所有项目都匹配。
答案 1 :(得分:0)
您可以使用Oracle INTERSECT SET Operator
select DT from table1
where WID in ('A')
INTERSECT
select DT from table1
where WID in ('B');