sql-query来比较字符串的确切数目和内容

9wbgstp7  于 2021-07-26  发布在  Java
关注(0)|答案(2)|浏览(180)

我想编写一个查询,返回成对的图书(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只有共同的'冒险'关键字,其他两个是不同的(你怎么能看到在表中关键字doi=1也有关键字'幻想'和doi=2有关键字'颤栗')。

hrirmatl

hrirmatl1#

如果我理解正确的话,你似乎希望第二个是第一个的超级集合。那就是:

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 条款。
(假设没有重复项。)
编辑:
您可以使用以下方法获得完全相同的关键字:

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对字符串长度的限制。

kxeu7u2r

kxeu7u2r2#

你可以用 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;

相关问题