#mysql #sql
#mysql #sql
Вопрос:
Не могли бы вы помочь мне с очень сложным вопросом?
У меня есть таблица ‘itemslog’ в СУБД MySQL с двумя столбцами: ‘userid’ и ‘itemid’, выглядит как:
| user1 | item 1 |
| user1 | item 2 |
| user2 | item 1 |
| user2 | item 2 |
| user2 | item 3 |
Мне нужно подсчитать, сколько пользователей имеют каждую пару элементов, например, ответить так:
| item1 | item2 | 2 |
| item1 | item3 | 1 |
| item2 | item3 | 1 |
Обычно мы можем использовать запрос на основе операций объединения, например:
SELECT
t1.itemname,
t2.itemname,
count(*)
FROM
itemslog AS t1
CROSS JOIN itemslog AS t2 ON t1.userid = t2.userid
WHERE
t1.itemname < t2.itemname
GROUP BY
t1.itemname, t2.itemname;
Но это требует много вычислений, и в моей ситуации это бесполезно (у меня около 200 тыс. строк). Можете ли вы дать мне совет, есть ли другие способы сделать это? Заранее благодарю вас!
Комментарии:
1. Мне непонятно, что вы пытаетесь здесь посчитать. Вы хотите узнать, есть ли у данного пользователя определенные элементы? Или что-то еще?
2. У вас есть другая таблица
items
, в которойitemid
есть первичный ключ — справочная таблица?3. Каждый пользователь может переносить любое количество элементов. Для каждой пары элементов я хочу подсчитать количество пользователей, которые несут их оба. В примере пары item1 и item2 содержат двух пользователей, а пары item1 и item3 — только одного.
4. Нет, у меня нет справочной таблицы. Но в моей ситуации это не проблема, если это поможет.
5. Вы объединяете одни и те же таблицы и извлекаете один и тот же столбец. Это даст вам одинаковый результат в обоих столбцах
Ответ №1:
Это ваш запрос:
SELECT t1.itemname, t2.itemname, count(*)
FROM itemslog t1 JOIN
itemslog t2
ON t1.userid = t2.userid AND t1.itemname < t2.itemname
GROUP BY t1.itemname, t2.itemname;
Для этого запроса вам нужен индекс на itemslog(userid, itemname)
:
create index itemslog_userid_itemname on itemslog(userid, itemname);
Предполагая, что у вас есть только несколько элементов для каждого userid
, это должно иметь разумную производительность.
Комментарии:
1. ВАУ!! Это выглядит как чертово чудо!) Это работает! Мне следует лучше разобраться в понимании работы с индексом. Большое тебе спасибо, парень!