SQL计算第二个表中一个表的单词出现次数

时间:2017-01-09 17:46:03

标签: mysql sql

我试图使用SQL的方言来解析一组记录。具体来说,我想计算在我的日志中包含各种ID(单词)的数字记录。我还想计算这些ID存在的总次数。

数据存在于两个不同的表中:

  • id_status - 包含idstatus的表格。
  • request_records - 包含请求记录的表。在给定记录中,id可能不止一次出现。

请参阅SQL Fiddle

id_status

此表包含ID及其当前状态。

id, status
sessions, ACTIVE
visits, DEPRECATED
duration, ACTIVE
...

request_records

句子记录可能包含超过30万条记录:

request
example.com/api?foo=sessions
example.com/api?bar=session%2Cvisits,foo=sessions
example.com/api?bar=duration,visits
example.com/api?foo=sessions
example.com/api?foo=visits,bar=visits
...

目标

我想创建一个包含四列id,status,occurence_count,record_count的表。

  • occurence_count:应该是所有记录中ID出现的总次数。
  • recourd_count:应该是特定id出现的记录总数。

根据上面的例子,我将生成下表:

id, status, occurence_count, recourd_count
sessions,ACTIVE,3,2
visits,DEPRECATED,4,3
duration,ACTIVE,1,1

SQL

有没有办法构建一个返回所需表的SQL查询?我会知道如何在Python或任何其他语言中相当容易地做到这一点但是如果可能的话我想写一个SELECT语句来生成这个表。

更新:如下所示,我试图执行以下操作:

SELECT ids.id, ids.status,
     SUM(length(request) - LENGTH(replace(request, ids.id, ''))) / LENGTH(ids.id) as occurence_count,
     COUNT(reqs.request) AS recourd_count
FROM id_status ids LEFT JOIN
     request_records reqs
     ON find_in_set(ids.id, reqs.requests) > 0
GROUP BY ids.id, ids.status;

但是我的SQL方言不允许这种类型的连接并返回以下错误:

ON clause must be AND of = comparisons of one field name from each table, with all field names prefixed with table name.

Sample Schema中添加了SQL小提琴:

CREATE TABLE id_status
    (`id` varchar(32), `status` varchar(32))
;

INSERT INTO id_status
    (`id`, `status`)
VALUES
    ('sessions', 'ACTIVE'),
    ('visits', 'DEPRECATED'),
    ('duration', 'ACTIVE')
;

CREATE TABLE request_records 
    (`request` varchar(500))
;

2 个答案:

答案 0 :(得分:3)

您可以使用查询生成所需内容。它效率不高:

select w.word, w.status,
       sum(length(sentence) - length(replace(sentence, w.word, ''))) / length(w.word) as cnt,
       count(s.sentence) as num_occurrences
from words w left join
     sentences s
     on find_in_set(w.word, s.sentence) > 0
group by w.word, w.status;

答案 1 :(得分:1)

简单版本:

SELECT id,
       status,
       (SELECT (SUM(CHAR_LENGTH(request)) -
                SUM(CHAR_LENGTH(REPLACE(request, id, ''))))
               / CHAR_LENGTH(id) FROM request_records) AS occurrence_count,
       (SELECT COUNT(*)
        FROM request_records
        WHERE INSTR(request, id) > 0) AS record_count
FROM id_status

请参阅updated SQL fiddle

这只是查找任何地方存在的单词,例如在查找abcsessions时会盲目地计算sessionsxyzsessions。如果需要更复杂的东西(例如考虑单词边界),您可能需要使用正则表达式替换器而不是REPLACE函数 - 但遗憾的是这是MySQL缺少的一件事。我曾经写过一篇文章,但这不是微不足道的 - 请参阅here