表格:
输入将是item_id的列表,例如2,3,4,而该输出将是在所有项目中找到的所有store_id ...因此:102,104
另一个示例输入:1,2,输出:102
MySQL是否提供此类操作?
首先,我需要对输入进行选择。然后,我可以将select中的所有store_id放入1个变量中,并找到出现n次(n为输入计数)的所有store_id?
为什么我的问题不同
我不是在问定界列表是好是坏,或者与之相关的任何事情。我在问,如何使用它来获得结果?
答案 0 :(得分:1)
您基本上是要从查找N个item_id的列表集中找到N个逗号分隔列表的交集。
您存储逗号分隔列表的方式确实使这变得更加困难。
要解决这个难题,我可以想到一种方法:
使用每个store_id创建一个表。
mysql> create table stores (store_id int primary key);
mysql> insert into stores values (101), (102), (103), (104);
现在,基于CSV与stores表中各个值的匹配,您可以将逗号分隔的列表中的store集合转换为许多行。
mysql> select * from mytable as t join stores as s on find_in_set(s.store_id, t.store_id)
where item_id in (2,3,4);
+---------+-----------------+----------+
| item_id | store_id | store_id |
+---------+-----------------+----------+
| 3 | 101,102,103,104 | 101 |
| 2 | 102,104 | 102 |
| 3 | 101,102,103,104 | 102 |
| 4 | 102,103,104 | 102 |
| 3 | 101,102,103,104 | 103 |
| 4 | 102,103,104 | 103 |
| 2 | 102,104 | 104 |
| 3 | 101,102,103,104 | 104 |
| 4 | 102,103,104 | 104 |
+---------+-----------------+----------+
然后按store_id
对这些行进行分组。假设您要搜索N个item_id,则这些计数为N的组就是符合条件的组。
mysql> select s.store_id, count(*)
from mytable as t join stores as s on find_in_set(s.store_id, t.store_id)
where item_id in (2,3,4)
group by s.store_id;
+----------+----------+
| store_id | count(*) |
+----------+----------+
| 101 | 1 |
| 102 | 3 |
| 103 | 2 |
| 104 | 3 |
+----------+----------+
您可以使用HAVING
子句将组过滤为所需的组。
mysql> select s.store_id, count(*)
from mytable as t join stores as s on find_in_set(s.store_id, t.store_id)
where item_id in (2,3,4)
group by s.store_id
having count(*) = 3;
+----------+----------+
| store_id | count(*) |
+----------+----------+
| 102 | 3 |
| 104 | 3 |
+----------+----------+
此问题不仅在于您需要具有列出所有store_id的另一个表,而且FIND_IN_SET()
函数效率低下并且无法通过索引进行优化。它一定要进行交叉联接,这意味着对于X个商品和Y个商店,它将对X个商品进行表格扫描,对于每个商品,它将对Y个商店进行表格扫描。随着您拥有更多的商店和物品,性能将与X * Y成正比。
这就是为什么当您确实需要在字符串中存储与单个ID进行比较的查询时,存储以逗号分隔的ID列表通常不是一个好主意的原因。
您应该拥有的是三个表:
示例:
mysql> create table store_has_item (item_id int, store_id int, primary key (item_id, store_id));
每对商品和存储行填充一行:
mysql> insert into store_has_item
-> select t.item_id, s.store_id from mytable as t join stores as s on find_in_set(s.store_id, t.store_id);
Query OK, 15 rows affected (0.02 sec)
Records: 15 Duplicates: 0 Warnings: 0
现在,您可以仅查询单个表中的N个项目(按store_id分组),然后返回计数为N的那些分组:
mysql> select store_id from store_has_item where item_id in (2,3,4)
group by store_id having count(*) = 3;
+----------+
| store_id |
+----------+
| 102 |
| 104 |
+----------+
答案 1 :(得分:-1)
MySQL是否提供此类操作?
当然,如果我理解正确,您只希望选择每个item_id可能获得的所有商店ID,您可以通过一条简单的语句来实现:
我找不到您的数据库布局,因此您必须根据需要进行处理:
SELECT
a.id, /* These id´s are your item_id´s */
GROUP_CONCAT(b.store_id) as store_ids /* These line puts your store_ids into one output */
FROM item_id a
JOIN store_id b ON b.item_id = a.id
GROUP BY item_id
此语句返回如下内容:
+ --------------- + ---------------------- +
| item_id | store_ids |
+ ----------- + ---------------------- +
| 1 | 120,210,330 |
| 2 | 90,10,30 |
| 3 | 70,120,90,330 |
+ ----------- + ---------------------- +
格里兹毒素