避免笛卡尔积检查对
avoid Cartesian product checking for pairs
我在 SQL Server 2014 中有两个 table:
- Table A 包含三列:Group、Proc 和 Date
- Table B 包含四列:Proc1、Proc2、Start、End
Table B 是 Proc 对的列表,如果组中的最小日期在开始和结束之间,则不应出现在 Table A 的同一组中。我试图在 Table A 中找到违反此规则的组,但问题是 Table A 有 60M 个组,每个组最多 100 行,而 Table B 有 65000 对.
其他人:
- 结尾可以为NULL
- Proc1 和 Proc2 的长度始终为 5 个字符,但 Proc 可以是任意长度
我的策略是
对于 A 中的每个组,获取最小日期并将 Proc 的所有唯一值填充到一个新字段 Procs 中,这些值用逗号分隔(该字段从不包含逗号)。使用 Group MinDate Procs 产生 table C。
取 C 和 B 的笛卡尔积,其中 (i) 开始和结束之间的 MinDate(或 > 开始和结束为 NULL)和 (ii) 如果我替换,Procs 的长度减少 10其中的 Proc1 和 Proc2 实例为空字符串。
此过程有效(在数据子集上),但我正在寻找有关如何将其扩展到完整数据集的建议。
如果您需要任何其他详细信息,请告诉我。谢谢!
如果我没理解错的话,你可以用连接来做到这一点。如果您在 b
.
中的每一行都有一个唯一标识符,那将会有所帮助
方法是将表连接在一起,然后计算 b
中每一行的违规次数:
select a.group, b.id, count(distinct a.proc) as num_procs
from a join
b
on a.proc in (b.proc1, b.proc2) and
a.date between b1.start and coalesce(b1.end, getdate())
group by a.group, b.id
having count(distinct a.proc) = 2;
如果没有b.id
,可以使用四列来标识每一行。
您的具体数据问题 proc
的长度是一个单独的问题。您应该修复您的数据,以便两个表之间应该匹配的字段实际上具有相同的类型。
我在 SQL Server 2014 中有两个 table:
- Table A 包含三列:Group、Proc 和 Date
- Table B 包含四列:Proc1、Proc2、Start、End
Table B 是 Proc 对的列表,如果组中的最小日期在开始和结束之间,则不应出现在 Table A 的同一组中。我试图在 Table A 中找到违反此规则的组,但问题是 Table A 有 60M 个组,每个组最多 100 行,而 Table B 有 65000 对.
其他人:
- 结尾可以为NULL
- Proc1 和 Proc2 的长度始终为 5 个字符,但 Proc 可以是任意长度
我的策略是
对于 A 中的每个组,获取最小日期并将 Proc 的所有唯一值填充到一个新字段 Procs 中,这些值用逗号分隔(该字段从不包含逗号)。使用 Group MinDate Procs 产生 table C。
取 C 和 B 的笛卡尔积,其中 (i) 开始和结束之间的 MinDate(或 > 开始和结束为 NULL)和 (ii) 如果我替换,Procs 的长度减少 10其中的 Proc1 和 Proc2 实例为空字符串。
此过程有效(在数据子集上),但我正在寻找有关如何将其扩展到完整数据集的建议。
如果您需要任何其他详细信息,请告诉我。谢谢!
如果我没理解错的话,你可以用连接来做到这一点。如果您在 b
.
方法是将表连接在一起,然后计算 b
中每一行的违规次数:
select a.group, b.id, count(distinct a.proc) as num_procs
from a join
b
on a.proc in (b.proc1, b.proc2) and
a.date between b1.start and coalesce(b1.end, getdate())
group by a.group, b.id
having count(distinct a.proc) = 2;
如果没有b.id
,可以使用四列来标识每一行。
您的具体数据问题 proc
的长度是一个单独的问题。您应该修复您的数据,以便两个表之间应该匹配的字段实际上具有相同的类型。