Revision1:我添加了一个精确除法的示例
这个操作被命名为关系分割。
在这种情况下,Table1(CatID, DealID) 是被除数,Table2(CatID) 是除数。
Table1(CatID, DealID) DIVIDED BY Table2(CatID) 运算的结果(商)表示具有相同 CatID(表 2)的所有 DealID(表 1)。
我不太清楚:您需要精确除法还是带余数的除法?
看看这个由 Joe Celko 写的article。
(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 为除数表(表 2 b)中的所有 CatID 值生成一个标识符。
- 基本查询将对股息表(表 1 a)中的记录进行分组:
GROUP BY a.DealID,并且对于每个 a.DealID 值,它会使用散列函数为来自 CatID 字段的所有值生成一个标识符:CHECKSUM_AGG( CHECKSUM(HASHBYTES('sha1',CAST(a.CatID AS VARCHAR(11)))) )。
风险:
- 有时,哈希函数会产生冲突(尤其是旧的哈希函数:CHECKSUM[_AGG])。
- 为了降低碰撞风险,我使用 HASHBYTES 函数。
- 根据我的测试(不知何故,这个问题对我来说已经很老了),我从未遇到过碰撞,但从不说永远。
- 解决方案按“原样”提供,不提供任何保证。
- 对于生产,请使用 Celko 解决方案之一。