避免笛卡尔积检查对

avoid Cartesian product checking for pairs

我在 SQL Server 2014 中有两个 table:

  1. Table A 包含三列:Group、Proc 和 Date
  2. Table B 包含四列:Proc1、Proc2、Start、End

Table B 是 Proc 对的列表,如果组中的最小日期在开始和结束之间,则不应出现在 Table A 的同一组中。我试图在 Table A 中找到违反此规则的组,但问题是 Table A 有 60M 个组,每个组最多 100 行,而 Table B 有 65000 对.

其他人:

我的策略是

  1. 对于 A 中的每个组,获取最小日期并将 Proc 的所有唯一值填充到一个新字段 Procs 中,这些值用逗号分隔(该字段从不包含逗号)。使用 Group MinDate Procs 产生 table C。

  2. 取 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 的长度是一个单独的问题。您应该修复您的数据,以便两个表之间应该匹配的字段实际上具有相同的类型。