SQL - подсчет наборов значений поля B для каждого значения поля A - PullRequest
0 голосов
/ 04 мая 2010

Прежде всего, извините, что не смог придумать более описательный заголовок.

Я хочу сделать следующее, используя только SQL:

У меня есть несколько списков строк, list1, list2 и list3.

У меня есть набор данных, который содержит два интересных столбца, A и B. Столбец A содержит TransactionID, а столбец B содержит ItemID.

Естественно, может быть несколько строк с одинаковыми идентификаторами транзакции.

Мне нужно перехватить те транзакции, которые имеют хотя бы один ItemID в каждом и каждом списке (list1 AND list2 AND list3).

Мне также нужно посчитать, сколько раз это происходит для каждой транзакции. [РЕДАКТИРОВАТЬ] То есть подсчитать, сколько полных наборов ItemID существует для каждого TransactionID "," Полный набор "- это любой элемент списка1 с любым элементом списка2 с любым элементом списка3

Надеюсь, в этом есть смысл, возможно, я смогу лучше объяснить это с ясной головой.

Заранее спасибо

Ответы [ 3 ]

0 голосов
/ 04 мая 2010

В MySQL, если у вас есть следующие списки:

list1 = ('1', '3')
list2 = ('2', '3')
list3 = ('3', '5')

тогда вы можете сделать это:

SELECT
    TransactionID,
    SUM(ItemID IN ('1', '3')) AS list1_count,
    SUM(ItemID IN ('2', '3')) AS list2_count,
    SUM(ItemID IN ('3', '5')) AS list3_count
FROM table1
GROUP BY TransactionID
HAVING list1_count > 0 AND list2_count > 0 AND list3_count > 0

Результат:

TransactionId  list1_count  list2_count  list3_count
1              3            2            1
3              2            2            1

Данные испытаний:

CREATE TABLE table1 (ID INT NOT NULL, TransactionID INT NOT NULL, ItemID INT NOT NULL);
INSERT INTO table1 (ID, TransactionID, ItemID) VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 1, 4),
(5, 1, 1),
(6, 2, 1),
(7, 2, 2),
(8, 2, 1),
(9, 2, 4),
(10, 3, 3),
(11, 3, 2),
(12, 3, 1);
0 голосов
/ 04 мая 2010

Если list1, list2 и list3 являются фактически известными перечислениями, вы можете перейти с:

SELECT TransactionID, COUNT(*)
FROM MyTable
WHERE ItemID IN (list1) AND ItemID IN (list2) AND ItemID IN (list3)
GROUP BY TransactionID

Если у вас много списков, вы можете сгенерировать SQL в программе. Тем не менее, он все равно должен работать довольно хорошо, даже для большого количества списков. Сначала поместите списки, которые, как вы ожидаете, будут иметь наименьшее количество совпадений, чтобы как можно скорее прекратить оценку предиката.

Если ваши списки находятся в другой таблице, возможно, в виде набора кортежей в форме (list_id, item_id), это более сложная проблема. Я хотел бы узнать больше, прежде чем пытаться придумать запрос для этого.

0 голосов
/ 04 мая 2010

В зависимости от вашего диалекта и предположения, что ваши списки - это другие таблицы ...

SELECT
    TransactionID, Count1, Count2, Count3
FROM
    MyDataSet M
    JOIN
    (SELECT COUNT(*), ItemID AS Count1 FROM List1 GROUP BY ItemID) T1 ON T1.ItemID = M.ItemID
    JOIN
    (SELECT COUNT(*), ItemID AS Count2 FROM List2 GROUP BY ItemID) T2 ON T2.ItemID = M.ItemID
    JOIN
    (SELECT COUNT(*), ItemID AS Count3 FROM List3 GROUP BY ItemID) T3 ON T3.ItemID = M.ItemID
...