[英]Count the number of unique rows after a group_concat aggregate in SQLite
I ask this on StackOverflow after carefully reading this answer about StackOverflow vs dba.se —I'm a non-expert database novice, and in my possibly-misguided estimation, a fellow non-DBA coder can help me just as well as a database expert.在仔细阅读了有关 StackOverflow 与 dba.se 的答案后,我在 StackOverflow 上提出了这个问题——我是一个非专家数据库新手,在我可能被误导的估计中,一位非 DBA 编码人员可以像数据库一样帮助我专家。 SQLite is also a “lite” database.
SQLite 也是一个“精简版”数据库。
My SQLite table is for, say, a recipes scenario.我的 SQLite 表用于,比如说,一个食谱场景。 It has two columns: each row has a field,
meal
and one ingredient
required by the meal.它有两列:每一行都有一个字段、
meal
和meal
所需的一种ingredient
。 Since most meals take more than one ingredient, there are many rows with the same meal
but different ingredient
s.由于大多数膳食采用不止一种成分,因此有许多行具有相同的
meal
但不同的ingredient
。
I need to know how many meals the exact set of ingredients can make—actually I need a sorted list of all the ingredients and how many meals can be made with exactly those ingredients.我需要知道一组确切的配料可以做多少餐——实际上我需要一份所有配料的分类清单,以及使用这些配料可以做多少餐。 I hope the code will explain this completely:
我希望代码能完整地解释这一点:
CREATE TABLE recipes (
meal TEXT,
ingredient TEXT);
INSERT INTO recipes VALUES
("tandoori chicken","chicken"), ("tandoori chicken","spices"),
("mom's chicken","chicken"), ("mom's chicken","spices"),
("spicy chicken","chicken"), ("spicy chicken","spices"),
("parmesan chicken","chicken"), ("parmesan chicken","cheese"), ("parmesan chicken","bread"),
("breaded chicken","chicken"), ("breaded chicken","cheese"), ("breaded chicken","bread"),
("plain chicken","chicken");
Here, we have在这里,我们有
I want something like the following:我想要类似以下内容:
chicken,,,spices|3
chicken,,,cheese,,,bread|2
chicken|1
That is, a string containing the exact set of ingredients and how many meals can be made using exactly these ingredients.也就是说,一个字符串包含确切的成分集以及使用这些成分可以制作多少餐。 (Don't worry about collating/sorting the ingredients, I can ensure that for each meal, rows will be inserted in the same order all the time. Also, don't worry about pathological cases where the same
meal
- ingredient
row is repeated—I can prevent that from happening.) (不用担心配料的整理/分类,我可以确保每顿饭,行会一直按相同的顺序插入。另外,不要担心同一
meal
- ingredient
行重复的病理情况——我可以防止这种情况发生。)
I can get the above output like this:我可以像这样得到上面的输出:
WITH t
AS (SELECT group_concat(recipes.ingredient, ",,,") AS ingredients
FROM recipes
GROUP BY recipes.meal)
SELECT t.ingredients,
count(t.ingredients) AS cnt
FROM t
GROUP BY t.ingredients
ORDER BY cnt DESC;
There's a couple of reasons I'm not happy with this: first, it creates a sub-view and I'm really curious if there's a way to achieve this without a sub-view—that would likely be faster and clearer.我对此不满意有几个原因:首先,它创建了一个子视图,我真的很好奇是否有办法在没有子视图的情况下实现这一目标——这可能会更快、更清晰。 And second, inside the sub-view, I create a string via group_concat to represent the vector of ingredients—I feel like there ought to be a row-based, or data structure -like, way to get the same information out of SQL.
其次,在子视图中,我通过group_concat创建了一个字符串来表示成分向量——我觉得应该有一种基于行或类似数据结构的方法来从 SQL 中获取相同的信息。
My question: can I get the above output, or some equivalent, without using sub-views and/or without string concatenation?我的问题:我可以在不使用子视图和/或不使用字符串连接的情况下获得上述输出或等效输出吗?
This simplification seems to work:这种简化似乎有效:
SELECT distinct group_concat(recipes.ingredient, ",,,")
, count(*) AS cnt
FROM recipes recipes
GROUP BY recipes.meal
ORDER BY cnt DESC;
It's really just a re-formulation of what you have already though, without the nested query or common table expression.它实际上只是对您已有内容的重新制定,没有嵌套查询或公用表表达式。
Since a recipe can have an arbitrary number of ingredients doing repeated joins isn't feasible (without recursion) so I think this is a great example of how handy the GROUP_CONCAT() function is.由于一个配方可以有任意数量的成分,重复连接是不可行的(没有递归),所以我认为这是一个很好的例子,说明 GROUP_CONCAT() 函数是多么方便。
Edit: Woops, you are right, sorry about that.编辑:Woops,你是对的,对此感到抱歉。 Looking at the problem again, I think that a separate result set is required.
再看问题,我觉得需要一个单独的结果集。 There are 2 levels of aggregation, one to 'pivot' the data so it is the recipe grain with a list of ingredients for each, and then another to count the number of recipies with the same ingredients list.
有 2 个聚合级别,一个用于“旋转”数据,因此它是具有每个成分列表的配方谷物,然后另一个用于计算具有相同成分列表的配方数量。 Below is a simple way to look at it, with the use of 'order by' in the GROUP_CONCAT to control the ordering, so the same list of ingredients is grouped together.
下面是一个简单的查看方式,在 GROUP_CONCAT 中使用“order by”来控制排序,因此相同的成分列表被分组在一起。 –
——
select ingredients_list, count(*) from ( SELECT meal, group_concat(recipes.ingredient, ",,," order by recipes.ingredient) as ingredients_list FROM recipes recipes GROUP BY recipes.meal ) meal_ingredients group by ingredients_list ;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.