在SQLite中将查询分组到尽可能少的查询中?

时间:2018-08-14 14:14:49

标签: sql sqlite

我不是数据库专家,但是我继承了我必须使用的SQLite数据库。它包含标签,图像和事件。一个事件包含多个图像,一个图像包含多个标签(这些标签描述了图像内容,例如咖啡,电话,笔记本电脑等)。

表结构看起来像这样:

row_id      tags          image_id          event_id

1           computer     1                 1
2           desk         1                 1
3           chair        1                 1

4           computer     2                 1
5           coffee       2                 1
6           desk         2                 1

7           dog          3                 2
8           phone        3                 2

etc.        etc.         etc.              etc.     // many 1000's

我们系统的用户过去常常通过选择一些标签来搜索图像,我们进行了一个非常简单的查询,该查询返回了一个排序列表,该列表倾向于包含最多标签的图像。看起来像这样:

SELECT image_id
FROM TagsTable
WHERE tags 
IN ('computer', 'desk', 'chair') // user variables
GROUP BY image_id
ORDER BY COUNT(image_id) DESC 

但是现在我们要返回事件列表(我需要对其进行排名),而不是返回单个图像。我可以通过在循环中执行许多查询来实现此目标,但这非常慢。理想情况下,我试图在尽可能少的查询中产生以下信息。

因此,如果用户搜索“计算机”,“办公桌”和“椅子”,您将获得...

event_id    computer_count      desk_count     chair_count    event_image_count    
1           12                  15             9              56                   
2           22                  0              13             24                   
3           14                  7              0              32
etc.        etc.                etc.           etc.           etc.

// no results if all tag counts are 0

因此,我们一眼就能看到事件1总共包含56张图像,标签“计算机”出现12次,“办公桌”出现15次,“椅子”出现9次。

是否可以仅使用SQL还是需要执行多个查询?请注意,我正在使用SQLite。

1 个答案:

答案 0 :(得分:2)

您可以使用条件聚合来回答这个特定问题:

SELECT event_id,
       SUM(CASE WHEN tags = 'computer' THEN 1 ELSE 0 END) as computer_count,
       SUM(CASE WHEN tags = 'desk' THEN 1 ELSE 0 END) as desk_count,
       SUM(CASE WHEN tags = 'chair' THEN 1 ELSE 0 END) as chair_count,
       COUNT(DISTINCT image_id) as image_count
FROM TagsTable
WHERE tags IN ('computer', 'desk', 'chair') 
GROUP BY event_id;

编辑:

要添加“平均”列:

SELECT . . .
       SUM(CASE WHEN tags IN ('computer', 'desk', 'chair') THEN 1.0 ELSE 0 END) / 3 as tag_average