Revision1: я добавил пример для точного деления
Эта операция называется реляционным делением.В этом случае Table1 (CatID, DealID) является дивидендом, а Table2 (CatID) является делителем.Результат (частное) операции Table1(CatID, DealID) DIVIDED BY Table2(CatID)
представляет все DealIDs (Таблица1), которые имеют одинаковые CatID (Таблица2).
Что-то не очень понятно для меня: вам нужно точное деление или деление с остатком?
Взгляните на эту статью , написанную Джо Селко.
(Revision1) Пример для точного деления (мои значения из таблицы (CatID, DealID) отличаются; объяснения и риски представлены ниже):
DECLARE @Table1 TABLE
(
DealID INT NOT NULL
,CatID INT NOT NULL
,PRIMARY KEY(DealID, CatID)
);
INSERT @Table1 (DealID, CatID)
SELECT src.DealID, src.CatID
FROM
(
SELECT 1 CatID, 668 DealID
UNION ALL
SELECT 2 CatID, 668 DealID
UNION ALL
SELECT 2 CatID, 669 DealID
UNION ALL
SELECT 1 CatID, 669 DealID
UNION ALL
SELECT 2 CatID, 671 DealID
UNION ALL
SELECT 11 CatID, 671 DealID
UNION ALL
SELECT 12 CatID, 671 DealID
UNION ALL
SELECT 11 CatID, 672 DealID
UNION ALL
SELECT 12 CatID, 672 DealID
UNION ALL
SELECT 13 CatID, 673 DealID
) src;
--Test1
DECLARE @Table2 TABLE
(
CatID INT NOT NULL PRIMARY KEY
);
INSERT @Table2
VALUES (1);
INSERT @Table2
VALUES (2);
SELECT CatID, DealID
FROM @Table1
ORDER BY DealID;
SELECT *
FROM @Table2
ORDER BY CatID;
SELECT a.DealID--, CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) Agg
FROM @Table1 a
GROUP BY a.DealID
HAVING CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) =
(
SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) )
FROM @Table2 b
);
--End of Test1
--Test2
DELETE @Table2;
INSERT @Table2
VALUES (11);
INSERT @Table2
VALUES (12);
SELECT a.DealID--, CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) Agg
FROM @Table1 a
GROUP BY a.DealID
HAVING CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) ) =
(
SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) )
FROM @Table2 b
);
--End of Test2
Пояснения:
- Этот подзапрос
SELECT CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(b.CatID AS VARCHAR(11)))) ) FROM @Table2 b
генерирует идентификатор для всех значений CatID из таблицы делителей (Таблица2 b). - Базовый запрос будет группировать записи из таблицы дивидендов (Таблица1 a):
GROUP BY a.DealID
и дляКаждое значение a.DealID генерирует идентификатор для всех значений из поля CatID с использованием хеш-функций: CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) )
.
Риски:
- Иногда хеш-функции могут генерироватьколлизии (особенно старые хеш-функции: CHECKSUM [_AGG]).
- Чтобы уменьшить риск коллизий, я использую функцию HASHBYTES.
- Из моих тестов (почему-то эта проблема для меня старая),Я никогда не сталкивался с коллиsions но никогда не говори никогда .
- РЕШЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ» БЕЗ ГАРАНТИИ.
- Для производства используйте одно из решений Celko.