SQL - 查询比较字符串的确切数量和内容。

问题描述 投票:0回答:2

我想写一个查询,返回成对的书籍(f_DOI, s_DOI),这些书籍符合以下条件:与s_DOI(第二本书)相关联的关键字也都与f_DOI(第一本书)相关联。

关键字

Doi   Keyword
1     'Adventure'
2     'Adventure'
1     'Fantasy'
2     'Thriller'
3     'Football'
4     'Football'
5     'History'

这是我的代码。

select k1.doi f_DOI , k2.doi s_DOI, k1.keyword
from keywords k1
join keywords k2
   on k2.doi > k1.doi
where k1.keyword= k2.keyword;

这是我的输出。

f_DOI s_DOI  KEYWORD
1     2     Adventure
3     4     Football 

第一行是不正确的,你可以看到f_DOI = 1和s_DOI = 2的共同点只有'Adventure'这个关键字,其他两个都是不同的(你可以看到在表中Keyword DOI = 1也有关键字'fantasy',DOI = 2有关键字'thriller')。

sql oracle inner-join
2个回答
1
投票

如果我的理解没错的话,你似乎希望第二本是第一本的超级集。 那就是。

with k as (
      select k.*, count(*) over (partition by doi) as cnt
      from keywords k
     )
select k.doi, k2.doi
from k join
     k k2
     on k2.keyword = k.keyword
group by k.doi, k2.doi, k.cnt
having count(*) = k.cnt;

如果你想要精确的匹配,那么包括 k2.cnt = k.cnton 子句。

(而这是假设没有重复的。)

EDIT:

你可以用以下方法获得完全相同的关键字:

with k as (
      select k.*, count(*) over (partition by doi) as cnt
      from (select distinct keyword, doi from keywords k) k
     )
select k.doi, k2.doi
from k join
     k k2
     on k2.keyword = k.keyword and k2.cnt = k.cnt
group by k.doi, k2.doi, k.cnt
having count(*) = k.cnt;

或者使用 listagg() 的方法。

select keywords, listagg(doi, ',') within group (order by keyword)
from (select doi,
            listagg(keyword, ',') within group (order by keyword) as keywords
      from (select distinct doi, keyword from keywords) k
      group by doi
     ) d
group by keywords;

这可能受到Oracle对字符串长度的限制。


0
投票

你可以使用 listagg 以下是:

With cte as
(Select t.doi, listagg(keyword,',') within group (order by keyword) as keyword
from your_table t
Group by t.id)
Select distinct t1.doi f_doi, t2.id s_doi, t1.keyword
From cte t1 join cte t2
On t1.adventure = t2.adventure
And t1.doi < t2.doi;
© www.soinside.com 2019 - 2024. All rights reserved.