【问题标题】:Query which displays a table along with indications of which rows match another table查询显示一个表以及哪些行与另一个表匹配的指示
【发布时间】:2018-09-14 13:30:51
【问题描述】:

我正在尝试获取一个表中的条形码编号列表,并确定另一个表中存在哪些条形码编号。同样,一组条码数字对应一个盒子,我还需要知道哪些盒子完全匹配并且可以丢弃。不幸的是,条形码编号有时包含无关的非数字字符,因此我在内部连接“ON”语句的两侧都使用了 REPLACE 函数。下面的查询可以很好地确定 table1 中的哪些项目存在于 table2 中。 (DOCINDEX245 是 table2 上的“条形码”列)

SELECT DISTINCT [BAR CODE]
        ,[Box]
  FROM Table1 ft
  INNER JOIN Table2 doc
  ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
  where REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')

我遇到的问题是,如果我尝试在 Table1 中查找 Table2 中不存在的行。

我试过这个:

SELECT DISTINCT [BAR CODE]
            ,[Box]
      FROM Table1 ft
      LEFT JOIN Table2 doc
      ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
      where REPLACE(doc.DOCINDEX245,'M','') is null

但是在我取消之前它运行了 20 分钟没有结果。

注意,Table1 是 10 列 x 60,000 行,Table2 是 300 列 x 140 万行。

在 DOCINDEX245 上有一个索引,我对其进行了重组,但它似乎没有做任何事情,或者无论如何都不够。

这一切都说了,如顶部所述,然后我需要确定哪些框是“完整的”,哪些有一些不匹配的行以及那些是哪些行。

所以我的理想结果应该是这样的:

BARCODE, BOX, MATCH
12345,box1,yes
12346,box1,yes
12347,box1,yes
12348,box2,yes
12349,box2,no
12350,box2,yes

我打算尝试使用上述两个查询的结果在 Excel 中手动创建它,但如果有一个查询可以做到这一点,我会全力以赴。

所以我想我在这里有多个问题,所以我愿意接受所有建议。

谢谢

【问题讨论】:

  • 你能提供样本数据和想要的结果吗?您所说的“对应”和“完全匹配”并不是很明显。
  • 确保你不需要在where中复制on

标签: sql sql-server sql-server-2008 join


【解决方案1】:

试试这个

SELECT [BAR CODE], [Box], 'yes' as match
  FROM Table1 ft
 INNER JOIN Table2 doc
    ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
union
SELECT [BAR CODE], [Box], 'no'
  FROM Table1 ft
  LEFT JOIN Table2 doc
    ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
 WHERE doc.DOCINDEX245 is null;

【讨论】:

  • 这绝对是我想要的,我今天晚些时候试试。
【解决方案2】:

您说得对,索引无济于事。这是由于在连接条件中使用了函数,在本例中为 REPLACE。这排除了索引的使用。理想情况下,您会使用以下形式:

ON ft.[BAR CODE] = doc.DOCINDEX245

为此,您可能需要使用持久计算列来删除无关字符。请参阅https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-computed-column-definition-transact-sql 上的 MS 文档(SQL 2008)

一旦定义了该列,就在其上放置一个索引,并在连接的 Table1 端的连接条件中使用它。

【讨论】:

  • 我想我要做的就是用我正在比较的字段创建一个新表。对于这个例子,我只是进行了一对一的比较,实际上我比较了几个字段以获得额外的 QA,但条形码是主要的。我认为将 140 万行表从 300 列减少到 4 列,并“清理”新表,因此我不再需要使用替换应该会产生很大的不同。
  • 我想感谢您的帮助,创建一个新表,即使没有索引也将左连接加速到几秒钟。
【解决方案3】:

Try below 它将为您提供 table1 中存在的所有记录、table2 中存在的 table1 记录、表 1 中不存在的 table2 记录。如果这是你想要的

SELECT DISTINCT [BAR CODE]
            ,[Box]
      FROM Table1 ft
      FULL OUTER JOIN Table2 doc
      ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
      where REPLACE(doc.DOCINDEX245,'M','') is null AND ft.[BAR CODE] IS NOT NULL

如果您的要求不同,请分享一些输入示例数据。

【讨论】:

  • 这与 LEFT JOIN 相同,只返回与 table2 中的行不匹配的行。
【解决方案4】:

当你的 Inner Join 工作正常时,你可以 Left Join 回到 Table1:

with cte as
 ( SELECT DISTINCT [BAR CODE]
        ,[Box]
   FROM Table1 ft
   INNER JOIN Table2 doc
     ON REPLACE(REPLACE(ft.[BAR CODE],'M',''),'-WDRN','') = REPLACE(doc.DOCINDEX245,'M','')
 )
select ft.*,
   case when cte.[BAR CODE] is null then 'no' else 'yes' end as match
FROM Table1 ft
LEFT JOIN cte
  ON ft.[BAR CODE] = cte.[BAR CODE]
 AND ft.[Box] = cte.[Box]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-24
    • 2011-08-15
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    • 2021-10-30
    相关资源
    最近更新 更多