【问题标题】:SQL Handling 2 tables efficiently by JoinsSQL 通过联接有效地处理 2 个表
【发布时间】:2017-12-31 11:06:48
【问题描述】:

我已经描述了我喜欢高效的 1 SQL 查询的场景。我曾尝试使用临时表,但我发现自己无处可去。征求专家意见。我正在使用 SQL Server 2012。

我有 2 个表 A 表和 B 表。

    Table A
    ID  TestName    

    Table B
    ID  TableAID LastUpdate 

表B中的TableAID是表A的ID列。

场景 1:

    Table A
    ID  TestName    
    1   Test 1      

    Table B
    ID  TableAID LastUpdate 

如果表B没有任何记录,则将表A的所有记录插入表B

场景 2:

    Table A
    ID  TestName    
    1   Test 1      

    Table B
    ID  TableAID LastUpdate
    1   1 

如果表A有记录并且匹配表B中的记录,则不做任何操作

场景 3:

    Table A
    ID  TestName 
    1   Test 1  
    2   Test 2      

    Table B
    ID  TableAID LastUpdate
    1   1 

如果表A有记录且表B中不匹配,则插入表B

场景 4:

    Table A
    ID  TestName


    Table B
    ID  TableAID LastUpdate
    1   1
    2   2 

如果表A没有记录,则更新表B中LastUpdate中所有记录的当前日期

我计划有 2 个临时表并使用 except 来过滤匹配的记录。但是我发现很难编写一个有效的查询。

【问题讨论】:

  • 场景4不应该发生,如果你使用外键也不会发生。
  • 表B中没有外键引用。表A是计算输出,可以当作临时表。

标签: sql performance sql-server-2012


【解决方案1】:

这似乎是使用MERGE 命令的完美借口

MERGE TableB b
USING TableA a ON a.ID = b.TableAID
WHEN NOT MATCHED BY TARGET
    THEN INSERT (TableAID) VALUES (a.ID)
WHEN NOT MATCHED BY SOURCE
    THEN UPDATE SET LastUpdate = GETDATE();

【讨论】:

  • NOT MATCHED BY SOURCE - 这是否意味着源表上根本没有记录?我怀疑您必须为此添加另一个条件。
  • @ZoharPeled 不,这意味着:对于 TableB 中的每条记录,在 TableA 中都找不到。不完全是OP的要求,但我猜更可能需要什么。如果 TableA 为空,那么就是 TableB 中的所有记录,因此它将在给定的场景中工作。
  • 但是......没有给出问题的场景 - 如果 TableB 有 2 条记录,而 TableA 有 1 条匹配记录 - 其他 TableB 行是否需要更新。这将更新它。如果这不好,这个想法就行不通了。
  • @ZoharPeled 场景 3 反之亦然:A 中有两条记录,B 中有一条记录?
  • @Nenad Zivkovic,对于您所问的情况,我总是先填充表 A,然后与表 B 进行比较。因此,如果表 A 有 2 条 ID 为 1 和 2 的记录,并且表 B 也有TableAID 1 和 2,我不更新。如果表 A 的 ID 为 1,而表 B 只有 TableAID 为 1 和 2,我只为 TableAID 2 更新 getDate 表 B
【解决方案2】:

对于场景 1、2 和 3,在我看来您只需要一个带有左连接的简单插入语句:

INSERT INTO [Table B] (TableAId)
SELECT a.ID
FROM [Table A] a
LEFT JOIN [Table B] b ON a.ID = b.TableAId
WHERE b.ID IS NULL

注意:我假设Table B 中的ID 列是identity,并且LastUpdate 列可以为空。

这会将存在于表 A 但不存在于表 B 中的所有记录插入表 B。

对于 senario 4,您需要一个更新语句:

UPDATE [Table B]
SET LastUpdate = GETDATE()
WHERE NOT EXISTS
(
    SELECT 1 FROM [Table A]
)

我看不出有一种方法可以让您在一个查询中完成所有 4 个场景。

【讨论】:

    猜你喜欢
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-03
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    相关资源
    最近更新 更多