SQL运算符IN仅返回DISTINCT

时间:2015-05-21 18:41:05

标签: mysql sql sqlite

我有以下查询:

SELECT class, subclass ,weight
FROM classes 
WHERE classes.term in ('this','paper','present','this','and','this','this') 

以上查询仅返回不同的值。例如,我有下表:

+-----------------------------------+
|class | subclass |  term  | weight |
+-----------------------------------+
|  a   |     b    |  this  |   3    |
|  c   |     d    |  paper |   2    |
|  e   |     f    |  sth   |   1    |
+-----------------------------------+

我将得到的结果是

+-----------------------------------+
|class | subclass |  term  | weight |
+-----------------------------------+
|  a   |     b    |  this  |   3    |
|  c   |     d    |  paper |   1    |
+-----------------------------------+

我真正想要的是以下

+-----------------------------------+
|class | subclass |  term  | weight |
+-----------------------------------+
|  a   |     b    |  this  |   3    |
|  a   |     b    |  this  |   3    |
|  a   |     b    |  this  |   3    |
|  a   |     b    |  this  |   3    |
|  c   |     d    |  paper |   2    |
+-----------------------------------+

我还有其他任何方法可以在没有IN"切割"只有不同的价值? 问题在于我无法改变这一部分:('这',' paper',' present',#39; this',' ;和''这''这') 因为它不是由查询创建的。这是我要搜索的一串单词。

修改   - 在原始场景中,该表包含超过3000个不同的单词,实际的字符串由我没有的函数生成    访问权限,包含300多个单词,包含许多重复项。   - 在原始场景中,我想添加每个单词的重量    它出现在字符串中的时间

EDIT2:

我期望的结果是每次术语出现在字符串中时对权重求和。 期待如下结果:

+-----------------------------------+
|class | subclass |  term  | weight |
+-----------------------------------+
|  a   |     b    |  this  |   12   |
|  c   |     d    |  paper |   2    |
+-----------------------------------+

还有其他解决方案吗?

2 个答案:

答案 0 :(得分:3)

使用join

select c.*
from (select 'this' as term union all
      select 'paper' as term union all
      select 'present' as term union all
      select 'this' as term union all
      select 'and' as term union all
      select 'this' as term union all
      select 'this' as term
     ) terms left join
     classes c
     on c.term = terms.term;

这适用于MySQL和SQLite。

答案 1 :(得分:1)

作为参考,请参阅此question,了解如何计算子字符串中出现的次数:

SELECT m.*, (LENGTH('this paper present this and this this') - LENGTH(REPLACE('this paper present this and this this', term, ''))) / LENGTH(term) AS count
FROM myTable;

获得每个字符串的出现次数后,您可以将该值乘以weight得到总数,如下所示:

SELECT term, weight * (LENGTH('this paper present this and this this') - LENGTH(REPLACE('this paper present this and this this', term, ''))) / LENGTH(term) AS totalWeight
FROM myTable m;

请注意,此解决方案不会采用单独的单词列表,而是将该列表连接成一个字符串。

以下是SQL Fiddle示例。

修改

如果您想要字符串中所有字词的权重总和,而不考虑字词本身,则可以调整查询以使用SUM()函数,并且不要使用{{1因为你想要对整个表进行求和:

GROUP BY

编辑2

基于长度的查询的更多解释。您可以将其分解为多个部分:

  1. SELECT SUM(weight * (LENGTH('this paper present this and this this') - LENGTH(REPLACE('this paper present this and this this', term, ''))) / LENGTH(term)) AS totalWeight FROM myTable m; 返回您要搜索的字符串中的字符数
  2. LENGTH('this paper present this and this this')是上面字符串的长度,删除了您的字词。 (所以,例如'这个',它的总长度为37,减去16(每次出现4次),这将给你21个。
  3. 通过从第一个值中减去第二个值,您将获得整个字符串中由于您的值而产生的字符数(37 - 21 = 16)。
  4. 然后,它将它除以术语的长度'获取出现次数。 16个字符,每次出现时除以4个字符表示子字符串出现4次。 (16/4 = 4)。请使用“纸张”再次尝试这些步骤。你会看到。
  5. 上述过程在此SQL Fiddle中逐步说明。