【问题标题】:SQL - Query to compare the exact number and content of stringsSQL - 查询以比较字符串的确切数量和内容
【发布时间】:2020-06-05 15:28:06
【问题描述】:

我想编写一个返回成对书籍 (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'关键字的共同点,其他两个不同(你可以在表格中看到关键字DOI = 1也有关键字 'fantasy' 和 DOI = 2 有关键字'thriller')。

【问题讨论】:

  • 在您的示例数据中没有调用 f_doi

标签: sql oracle inner-join


【解决方案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;

如果您想要完全匹配,请在 on 子句中包含 k2.cnt = k.cnt

(并且假设没有重复。)

编辑:

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

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

【讨论】:

  • 我试过这个查询,它似乎工作(除了我有 [1 1, 3 3, etc ...] 的重复项还添加到 k2.cnt = k.cnt )。但是我在请求中肯定不清楚,对此感到抱歉,我试图从我的查询中得到以下结果:DOI 3 和 4,因为它们是唯一具有相同关键字的 DOI。要得到这个结果,part by子句是唯一的方法吗?
  • @Gwynbleidd 。 . .子集/超集方法和完全匹配之间存在很大差异。我已经编辑了答案以提供两种解决方案。
【解决方案2】:

您可以按如下方式使用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;

【讨论】:

  • 通过这个查询,我必须提前知道哪些是关键字,对吧?问题是我需要写一个“通用查询”,不指明关键字。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多