【问题标题】:SQL Difference function between Name Column in 2 Tables2表中名称列之间的SQL差异函数
【发布时间】:2017-03-10 16:47:10
【问题描述】:

我有 2 个表,其中包含一个名称部分的列,即 John Doe 有一行用于 John,一个用于 Doe。这两个表有不同的名称。我需要从一个表中获取名称部分并计算与另一个表中名称部分的差异分数。现在我正在使用一个内部和外部光标来遍历两个表中的每一个。这有效,但需要很长时间才能运行。

有没有其他方法可以加快速度?

我正在尝试做的一个例子:

表 1

Name
----
John
Doe
Jan
Smith

表 2

Name
-----
Henry
Ford
Ransom
Eli
Olds

这是我需要的:

DIFFERENCE('John','Henry')
DIFFERENCE('John','Ford')
DIFFERENCE('John','Ransom')
DIFFERENCE('John','Eli')
DIFFERENCE('John','Olds')
DIFFERENCE('Doe','Henry')
DIFFERENCE('Doe','Ford')
DIFFERENCE('Doe','Ransom')
DIFFERENCE('Doe','Eli')
DIFFERENCE('Doe','Olds')
DIFFERENCE('Jane','Henry')
DIFFERENCE('Jane','Ford')
DIFFERENCE('Jane','Ransom')
DIFFERENCE('Jane','Eli')
DIFFERENCE('Jane','Olds')
DIFFERENCE('Smith','Henry')
DIFFERENCE('Smith','Ford')
DIFFERENCE('Smith','Ransom')
DIFFERENCE('Smith','Eli')
DIFFERENCE('Smith','Olds')

现在,我将这些 DIFFERENCE 分数保存在临时表中以用于测试目的。很抱歉缺少格式,我是在这里发帖的新手。谢谢你的帮助。

【问题讨论】:

  • 那么问题到底是什么?
  • 我有一个包含超过 28,000 条记录的表,并且正在将它与另一个包含超过 5,000 条记录的表进行比较。除非我做错了数学运算,否则这将生成超过 160,000,000 条组合记录,并且需要 3.5 多个小时来处理。是否有更快的过程来减少可能需要的时间?谢谢。
  • @carl20236 由于您是这里的新手(顺便说一句:欢迎!),请允许我提示:您非常好心,请在(最佳)答案的投票计数器下方勾选接受检查。这将 1) 将此问题标记为已解决 2) 让追随者更容易找到最佳解决方案 3) 向回答者支付积分和 4) 向您支付积分。一旦您自己越过了 15 点边界,您还被要求对贡献进行投票。这是说谢谢的方式。快乐编码!

标签: sql sql-server tsql sql-server-2008-r2 cross-join


【解决方案1】:

我认为 - 你真正在寻找的 - 是 CROSS JOIN

简而言之,它是一个 join-everything-with-everything 连接,不需要连接条件。结果是每个可能的值组合,换句话说:笛卡尔积

试试这个:

DECLARE @tbl1 TABLE(Name VARCHAR(100));
INSERT INTO @tbl1 VALUES
 ('John')
,('Doe')
,('Jan')
,('Smith');

DECLARE @tbl2 TABLE(Name VARCHAR(100));
INSERT INTO @tbl2 VALUES
 ('Henry')
,('Ford')
,('Ransom')
,('Eli')
,('Olds');

SELECT t1.Name
      ,t2.Name
      ,DIFFERENCE(t1.Name,t2.Name) AS DiffName
FROM @tbl1 AS t1
CROSS JOIN @tbl2 AS t2

结果

Name    Name    DiffName
John    Henry   2
Doe     Henry   2
Jan     Henry   2
Smith   Henry   2
John    Ford    2
Doe     Ford    2
Jan     Ford    2
Smith   Ford    2
John    Ransom  1
Doe     Ransom  0
Jan     Ransom  1
Smith   Ransom  1
John    Eli     2
Doe     Eli     2
Jan     Eli     2
Smith   Eli     1
John    Olds    0
Doe     Olds    0
Jan     Olds    0
Smith   Olds    1

【讨论】:

  • 因文档而被投票赞成,准备测试代码和结果。另一种方式:SELECT T1.Name, T2.Name, DIFFERENCE(T1.Name, T2.Name) AS 'Difference' FROM (VALUES ('John'),('Doe'),('Jan'),('Smith')) T1 (Name) CROSS JOIN (VALUES ('Henry'),('Ford'),('Ransom'),('Eli'),('Olds')) T2 (Name)
【解决方案2】:

您可以使用笛卡尔连接..或交叉连接。

SELECT DIFFERENCE(t1.Name, t2.Name) 
FROM Table1 t1
CROSS JOIN Table2 t2

For Reference

【讨论】:

    【解决方案3】:

    这是另一种更简单的写法:

    SELECT table1.name, table2.name, DIFFERENCE(table1.Name, table2.Name)
    FROM table1, table2
    

    【讨论】:

    • 正确的是,FROM-sources 的简单逗号分隔列表没有任何WHERE-clause 将创建与CROSS JOIN 完全相同的列表。但是有一些例子说明为什么应该首选CROSS JOIN,尤其是在涉及进一步连接或APPLYs 时。如果这更简单实际上是一个品味问题......
    • @Shnugo 有哪些例子?
    • 使用我的答案的完整代码并添加一行CROSS APPLY(SELECT t1.Name+t2.Name AS Combined) AS x。将x.Combined 添加到选择列表中。这将起作用并显示连接的两个名称。现在尝试使用逗号并找到超出范围的t1.Name...
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-09
    相关资源
    最近更新 更多