我有三张桌子:
表格1
table1
可以有 50K 到 800k 的唯一行。我的意思是每行中所有值的组合都是唯一的,尽管有时某些列会匹配。除了列之外,整行都可能匹配NAME
,但这是非常非常不可能的。NAME 列将始终是唯一的。
该NAME
列是 type varchar(20)
。每条记录的其余列都是 type varchar(6)
,其中每两列是一个集合对,表有多达 21 个集合对(即总共 43 列)。这是一个table1
显示 4 条记录的一组对的示例(为了方便起见,我在这里使用了单个字符,但不要忘记它们是 type varchar(6)
):
table1
NAME pair1_1 pair1_2 ...up to pair21_1 - pair21_2
00001A A B
00002A A A
00003A B C
00004A A B
…up to 800k rows
表2
table2
设置方式完全相同,只是它包含完全相同类型的完全不同的记录(这里可以有 1 到 200 行)
table2
NAME pair1_1 pair1_2 ...up to pair21_1 - pair21_2
1234B A B
5678B A A
9101B C C
1213B A B
…up to 200 rows
表3
table3
与 in 中的单行相关联,table2
并且可以表征为该单行 intable2
与可能位于 中的任何可能行之间的比较的每个可能结果table1
。最好通过与它相关的NAME
in来调用table2
它(让我们只使用第一个并调用它,table1234B
因为如果 table2 中有 200 行,则有 200 个不同的关联table3
s)。
第 3 个表将包含 4 行。它有一NAME
列是 avarchar(20)
和 21 组 7 列(每列与 和 的不同对相关联table1
)table2
。额外的列res1_1
是res1_2…res21_7
type decimal(30,7)
。
这是它的样子:
table1234B
NAME res1_1 res1_2 res1_3 res1_4 res1_5 res1_6 res1_7 ….res21_7
1234B 12.30 1.000 0.2500 1.000 2.000 2.10 25.00 ….
我想使用来自table1
和的列对中的共享数据的组合table2
(即它们如何匹配)作为从中选择数据的条件table1234B
(我将在下面展示其中的一些)。只会比较重合的对。pair1_1
and pair1_2
fromtable1
将与 topair1_1
和pair1_2
from进行比较table2
,pair2
s 将仅与pair2
s 进行比较,pair3
s 仅与pair3
s 进行比较等。因此,不会进行交叉对比较(例如pair1
,永远不会与 进行比较pair2
)
在下面的示例中,pair1_1
每个表中的字段匹配 (A),pair1_2
每个表中的字段匹配 (B),但每个表的列之间的字段不匹配。
NAME Pair1_1 Pair1_2
00001A A B (from table1)
1234B A B (from table2)
所以我想 SELECT 说pair1_4
fromtable1234B
并将其与记录 00001A 和 1234B 之间的比较相关联。
如果表格是这样的,我们可以看到所有 4 个字段都匹配。
NAME pair1_1 pair1_2
00001A A A (from table1)
1234B A A (from table2)
在这种情况下,也许我想pair1_1
选择table1234B
在这里我们可以看到pair1_1
intable1
匹配两个字段 fromtable2
但pair1_2
fromtable1
不匹配任何内容。
NAME pair1_1 pair1_2
00001A A B (from table1)
1234B A A (from table2)
所以我想选择say pair1_4
fromtable1234B
以上只是列对中的数据可以在表之间共享的 14 种可能方式中的 3 种(它们也有多种方式在表之间不共享数据),但每对只有 7 种可能的列可供选择table1234B
。
我想从和table1234B
的每组 2 中的列之间的所有可能共享中选择符合标准的所有值。完成后看起来像这样:table1
table2
1234BResult
NAME RESULTPair1 …up to Resultpair21
00001A 12.30 (res1_1 from table3)
00002B 1.000 (res1_2 from table3)
00003C 25.00 (res1_7 from table3)
00004A 1.000 (res1_4 from table3)
…up to 800K rows
这是我开始编辑的查询。
SELECT t1.NAME as NAME, t3.pair1_4 as RESULTPair1
FROM table1 t1
LEFT OUTER JOIN table2 t2
ON (t1.pair1_1 = t2.pair1_1 AND t1.pair1_1 <> t1.pair1_2 AND t1.pair1_2 = t2.pair1_2 AND t2.pair1_1 <> t2.pair1_2)
LEFT OUTER JOIN table1234B t3
ON t2.NAME = t3.NAME
…以及该查询的结果
NAME RESULTPair1
00001A 1.000 (res1_4 from table3)
00002B NULL
00003A NULL
00004A 1.000 (res1_4 from table3)
这更接近我正在寻找的内容,因为它使NAME
stable2
具有不同的共享对来自 的其他值开放table1234B
。我打算合并后的剩余逻辑将返回其他适当的结果。
麻烦的是,这只会给我任何情况的结果,即 AB,AB。我需要将其扩展到 21 对和可能table3
的 200 对,包括所有不同的可能结果(table3
如果适用)。我可以处理所有共享逻辑(即pair1_1 = pairt2_2
或pair1_1 <> pair2_2
),它将其扩展到其余情况以及可能更多table2
我不知所措的记录。我需要获得table1
所有 21 对中所有 800k 记录的结果。
如果你和我待了这么久并且理解所有的鸡抓,我的问题是:
- 我将如何编辑上面的查询以使用 a
JOIN
而不是 aWHERE
? - 是否有一种方法可以扩展它以有效地包含在字段之间共享的其他可能场景的逻辑,
table1
以便table2
我可以在新表中查看或存储从table1
单行到单行的所有 50-800k 结果table2
? - 我怎么把它扩展到额外的 20 对?
编辑 在被问及与 table3 的连接后,我意识到该列需要编辑才能正常工作。我仍然无法弄清楚如何使查询正常工作。我也编辑了查询。我仍然在将其扩展到多个列时遇到了一些麻烦。建议使用 INTERSECT + EXCEPT 或 NOT EXISTS。我无法让 INTERSECT 返回任何内容,而带有编辑以包含左连接的查询确实如此。
我有一个有效的查询。它连接了 21 个派生表(比较的 21 对中的每一对都有一个)。它们是用 20
FULL OUTER JOIN
s 而不是LEFT JOIN
s 连接的,每个都有 14 个子查询的集合和UNION ALL
s 组合,所以我将给出一个带有一些评论的一般形式。它在 5 秒内完成了 67,000 次比较。这是一项正在进行的工作,所以如果我可以做些什么来改进它,请告诉我!就像我在上面的评论中所说的那样,我想我要设置另一个表来将 varchar(6) 字段索引为整数,然后使用整数进行比较。所以现在 table1 和 table2 看起来像这样:
...以及使比较更快的附加索引,以防我想检索实际的数据集:
我添加了索引表,现在可以比较整数而不是 varchar(6) 列。67,000 table1 行查询在 5 秒内为 varchar(6) 列生成 21 列,而对于整数列则为 4 秒。140 万次计算。有人有任何其他建议可以帮助我吗?