【问题标题】:SQL self join - SQL and AccessSQL 自联接 - SQL 和 Access
【发布时间】:2022-01-16 10:17:22
【问题描述】:

表1

ID Code Decision
1 TK01 Yes
2 OP01 ---
3 TK01 ---
4 MK02 Yes
5 MK02 ---

大家好, 如果在 Code 列中发现重复项,什么 SQL 查询将更新 Decision 列。

换句话说: 带有 Code 的 ID 1 TK01 为“是”,因此 ID 3 应在 Decision 列中更新为“是”值。

与 ID 5 相同,因为它与 ID 4 的代码匹配,并且 ID 4 在 Decision 列中具有“是”值。

我已经在 Access(下面的代码)中创建了它,但是请在 t-sql 或 mysql 中创建它

UPDATE Table1 t1 INNER JOIN Table1 t2
ON t1.Code = t2.Code
SET t1.Decision  = t2.Decision

【问题讨论】:

  • 这已经是可以在 MSSQL 或 MySQL 中工作的有效 SQL。其中没有任何特定于访问的内容。
  • @Peter 那UPDATE SQL 在 SQL Server 中不起作用。 SQL Server 对此有不同的UPDATE ... SET ... FROM 语法。
  • 该语法肯定会失败,尽管即使在 Access 中,仅在 code 上的自连接会为 decision 的每个值复制行,所以如果两行都设置为“是”或“---”,那将是任意的

标签: sql ms-access


【解决方案1】:

tsql:

UPDATE t1 SET t1.Decision = 'Yes' FROM Table1 t1 INNER JOIN Table1 t2 ON t1.Code = t2.Code
WHERE t1.Decision <> t2.Decision

您可以通过在块中添加 UPDATE 语句来查看预期结果而无需执行它

BEGIN TRAN
SELECT * FROM Table1

UPDATE t1 SET t1.Decision = 1 FROM Table1 t1 
INNER JOIN Table1 t2 ON t1.Code = t2.Code
WHERE t1.Decision <> t2.Decision

SELECT * FROM Table1

ROLLBACK TRAN

【讨论】:

    【解决方案2】:

    在 T-SQL 中,我会使用一个可更新的 CTE 来做到这一点。使用分析函数,获取正确的 decision 值并识别 code 重复项,然后仅更新那些重复项:

    with u as (
        select *,
          Max(decision) over(partition by code) v, 
          Count(*) over(partition by code) cnt
        from t
    )
    update u
    set decision = v
    where cnt > 1 and decision = '---'
    

    【讨论】:

      【解决方案3】:

      这应该可行:

      UPDATE a
      SET decision = 'Yes'
      FROM table1 AS a
         INNER JOIN table1 AS b
             ON a.code = b.code
                AND (a.decision = 'Yes' OR b.decision = 'Yes');  
      

      不过,您应该规范化您的表格。如果决策仅取决于代码,您应该考虑将决策列移动到新表中,这样您就有两个表U(ID, Code)V(Code, Decision)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-23
        • 1970-01-01
        • 1970-01-01
        • 2021-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多