我无法弄清楚我认为必须是一个非常简单的问题。我真的很生气我把这个问题搞得很困难,但我已经准备好问别人了。
我有一个基本上是一堆键值对的表,其中键和值都可以重复。我有另一个表可以用来过滤第一个表中的值。
我想从第二个表中获取值,并使用它来过滤第一个表中的键值对,并获得GROUP BY计算第一个表中剩余的键数。我还希望当第二个表导致给定键的所有行被过滤掉时,该计数返回0。
我知道可能很难想象,所以这里有一个SQL Fiddle链接: http://sqlfiddle.com/#!4/c186ef
不幸的是,我似乎无法让SQL Fiddle运行我放在那里的查询,即使我可以在我的IDE中运行它。但希望这能传达出我想要做的事情。 以下是我一直在尝试对付SQL Fiddle中的表的SQL语句:
SELECT mtkv2.key, COALESCE(count(mtkv2.value), 0) cnt
FROM matt_test_key_values mtkv1
RIGHT OUTER JOIN matt_test_key_values mtkv2 ON mtkv1.key = mtkv2.key
WHERE mtkv2.value in (SELECT value FROM matt_test_values)
GROUP BY mtkv2.key
SELECT mtkv1.key, COALESCE(count(mtkv1.key), 0) cnt
FROM matt_test_key_values mtkv1
WHERE mtkv1.value not in (SELECT value FROM matt_test_values)
GROUP BY mtkv1.key
SELECT mtkv1.key, COALESCE(count(mtkv1.value), 0) cnt
FROM matt_test_key_values mtkv1
LEFT JOIN matt_test_key_values mtkv2 ON mtkv1.key = mtkv2.key
AND mtkv1.value = mtkv2.value
AND mtkv2.value IN (SELECT value FROM matt_test_values)
GROUP BY mtkv1.key
我一直在搞乱不同的SQL,所以此时可能还有其他一些错误。我并没有问过如何解决这些问题,因为我试图找出应该如何正确地完成这些工作
示例数据可以在SQL Fiddle中看到,但这里只是以下情况:
create table matt_test_values (value varchar2(200))
insert into matt_test_values values('1')
create table matt_test_key_values (key varchar2(200), value varchar2(200))
insert into matt_test_key_values values('1', '1')
insert into matt_test_key_values values('1', '2')
insert into matt_test_key_values values('1', '3')
insert into matt_test_key_values values('2', '1')
insert into matt_test_key_values values('2', '2')
insert into matt_test_key_values values('3', '1')
insert into matt_test_key_values values('4', '2')
我希望获得的输出类似于:
key cnt
--- ---
1 2 //after removing the "1" value that matches, there are two rows left
2 1 //after removing the "1" value that matches, there is one row left
3 0 //after removing the "1" value that matches, there are zero rows left - this is the result I am having trouble getting
4 1 //after removing the "1" value that matches, there is one row left
答案 0 :(得分:1)
技巧是捕获所有值都被消除的键的零计数。此解决方案使用子查询来获取所有键的集合;外连接意味着当剩余键组中没有匹配时,你将得到0。
with cte as (
select distinct key
from matt_test_key_values
)
, mtkv as (
select * from matt_test_key_values
where value not in ( select mtv.value from matt_test_values mtv)
)
select cte.key
, count(mtkv.value) vals
from cte
left outer join mtkv
on mtkv.key = cte.key
group by cte.key
order by cte.key
/
"键和值都可以重复"
我的解决方案计算所有键/值对而不是不同的键/值对。如果这不是您想要的,那么改变逻辑就很容易了。
答案 1 :(得分:1)
How about
select distinct m.key, nvl( g.c, 0 )
from matt_test_key_values m
left join (
select k.key, count(*) c
from matt_test_key_values k
left join matt_test_values v
on k.value = v.value
where v.value is null
group by k.key
) g
on m.key = g.key
答案 2 :(得分:0)
示例输出会很有帮助,但是根据您的描述,它听起来像这样:
select key, count(*)
from matt_test_key_values
where value not in ( select value from matt_test_values )
group by key