【问题标题】:Updating a Column based on 3 tables?更新基于 3 个表的列?
【发布时间】:2011-11-10 09:04:24
【问题描述】:

我有 3 张桌子,例如

缩进头:

 IndentID        StatusID 
--------         ------   
    1             5      
    2             5

缩进细节:

IndentID         ItemID           ItemStatusID
--------         ------           ------------
 1                22                 4
 1                23                 4
 2                11                 4
 2                12                 3
 2                13                 3

点缩进:

       POID             IndentID     ItemID      ItemStatusID
      --------           ------      ------      ------------
         1                1            22            4
         1                1            23            4
         1                2            11            4

当 IndentDetail 表中的所有项目(基于 IndentID)ItemstatusID 变为 4 时,我想更新 IndentHeader 表 StatusID = 4,否则我想更新 IndentHeader StatusID = 3。在条件中我需要提供 POID。根据 POID,IndentHeader 和 IndentDetail 表都考虑相应的 Indent。我想要的结果应该是这样的:

缩进头:

 IndentID        StatusID 
--------         ------   
    1             4      
    2             3

如何做到这一点?请帮帮我。

大家好,这是我的更新命令。但它会将 IndentHeader 中的 StatusID 都更新为 4。

   UPDATE STR_IndentHeader
            SET StatusID = IID
            FROM
            (SELECT 
            STR_IndentDetail.IndentID, MIN(ItemStatusID) AS 'IID'
            FROM 
            STR_IndentDetail INNER JOIN PUR_POIndent PP
            ON PP.IndentID = STR_IndentDetail.IndentID
            AND PP.ItemID = STR_IndentDetail.ItemID
                        WHERE ItemStatusID = 4 AND PP.POID = 1
            GROUP BY STR_IndentDetail.IndentID) ID 
            WHERE ID.IndentID = STR_IndentHeader.IndentID 

我需要你所有的宝贵贡献。请帮帮我...

【问题讨论】:

  • 你知道 UPDATE 命令吗?如果是这样,您至少应该尝试一下并向我们展示您的尝试。
  • @Andrew:我发布了我的更新查询。请看一下。
  • 当你说“这里我只想传递 POID,所以剩下的应该按照表格关系发生在上面”时,你的实际意思是什么?这没有意义。
  • @Hugh:在这种情况下,我需要提供 POID。因此,根据 POIndent 表中 POID 对应的 IndentID,应该执行更新查询。

标签: sql sql-server sql-server-2005 join sql-update


【解决方案1】:

它的要点是

  • 找到每个IndentID 的最小值ItemStatusID
  • IndentHeader 一起回来
  • UPDATE FROM 语句中使用这些

SQL 语句

UPDATE  IndentHeader
SET     StatusID = ihd.ItemStatusID
FROM    IndentHeader ih
        INNER JOIN (
            SELECT  ItemStatusID = MIN(id.ItemStatusID)
                    , ih.IndentID
            FROM    IndentHeader ih
                    INNER JOIN IndentDetail id ON id.IndentID = ih.IndentID
                    INNER JOIN POIndent pi ON pi.IndentID = id.IndentID
            WHERE   pi.POID = 1     
            GROUP BY
                    ih.IndentID     
        ) ihd ON ihd.IndentID = ih.IndentID         

测试脚本

;WITH IndentHeader (IndentID, StatusID) AS (
    SELECT 1, 5      
    UNION ALL SELECT 2, 5
)
, IndentDetail (IndentID, ItemID, ItemStatusID) AS (
    SELECT 1, 22, 4
    UNION ALL SELECT 1, 23, 4
    UNION ALL SELECT 2, 11, 4
    UNION ALL SELECT 2, 12, 3
    UNION ALL SELECT 2, 13, 3
)
, POIndent (POID, IndentID, ItemID, ItemStatusID) AS (
    SELECT 1, 1, 22, 4
    UNION ALL SELECT 1, 1, 23, 4
    UNION ALL SELECT 1, 2, 11, 4
)
--UPDATE    IndentHeader
--SET       StatusID = ihd.ItemStatusID
SELECT  ih.IndentID, ihd.ItemStatusID
FROM    IndentHeader ih
        INNER JOIN (
            SELECT  ItemStatusID = MIN(id.ItemStatusID)
                    , ih.IndentID
            FROM    IndentHeader ih
                    INNER JOIN IndentDetail id ON id.IndentID = ih.IndentID
                    INNER JOIN POIndent pi ON pi.IndentID = id.IndentID
            WHERE   pi.POID = 1     
            GROUP BY
                    ih.IndentID     
        ) ihd ON ihd.IndentID = ih.IndentID         

【讨论】:

  • mmm...您已编辑您的问题以包含您当前的查询。乍一看,它看起来与我的建议相同,但 AFAIK,查询是有效的。我得写一些测试脚本
  • @thevan:测试脚本为 IndentID 1 输出 ItemStatusID 4,为 IndentID 2 输出 ItemStatusID 3。这不是您需要的吗?
  • @thevan:测试脚本为 IndentID 1 输出 ItemStatusID 4,为 IndentID 2 输出 ItemStatusID 3。这不是您需要的吗?
  • @thevan:这是一个有价值的起点。如果这不是最终的解决方案,对事件进行投票是礼貌和正确的。
  • @thevan - 别提了,但我仍然对为什么这对你不起作用感到困惑。
【解决方案2】:

我的 [修订] 解决方案使用一个 ALL 子查询来检查 ItemStatusID 条件:

DECLARE @MyPOID INT = 1;

DECLARE @IndentHeader TABLE
(
    IndentID INT PRIMARY KEY
    ,StatusID INT NOT NULL
);
INSERT  @IndentHeader 
VALUES  (1,5);
INSERT  @IndentHeader 
VALUES  (2,5);
INSERT  @IndentHeader 
VALUES  (3,5);

DECLARE @IndentDetail TABLE
(
    IndentID INT NOT NULL
    ,ItemID INT NOT NULL
    ,ItemStatusID INT NOT NULL
    ,PRIMARY KEY(IndentID, ItemID)
);
INSERT  @IndentDetail
VALUES  (1,22,4);
INSERT  @IndentDetail
VALUES  (1,23,4);
INSERT  @IndentDetail
VALUES  (2,11,4);
INSERT  @IndentDetail
VALUES  (2,12,3);
INSERT  @IndentDetail
VALUES  (2,13,3);
INSERT  @IndentDetail
VALUES  (3,22,3);

DECLARE @POIndent TABLE
(
    POID INT
    ,IndentID INT NOT NULL
    ,ItemID INT NOT NULL
    ,ItemStatusID INT NOT NULL
);
INSERT  @POIndent 
VALUES  (1,1,22,4);
INSERT  @POIndent 
VALUES  (1,1,23,4);
INSERT  @POIndent 
VALUES  (1,2,11,4);
INSERT  @POIndent 
VALUES  (2,3,22,4);

SELECT  *
FROM    @IndentHeader h;
SELECT  *
FROM    @IndentDetail d;
SELECT  *
FROM    @POIndent po;

UPDATE  @IndentHeader 
SET     StatusID = CASE WHEN 4 = ALL(SELECT d.ItemStatusID FROM @IndentDetail d WHERE d.IndentID = h.IndentID) THEN 4 ELSE 3 END
FROM    @IndentHeader h
WHERE   h.IndentID IN (SELECT po.IndentID FROM @POIndent po WHERE po.POID = @MyPOID);

SELECT  *
FROM    @IndentHeader h;

【讨论】:

  • 是的。但它会更新所有 IndentID 的 StatusID。但我只想更新 POINdent 表中对应 POID 的 IndentID。
  • @thevan:这是一个有价值的起点。如果这不是最终的解决方案,对事件进行投票是礼貌和正确的。
  • @Sahleen:谢谢你,sahleen。这个陈述为我的问题提供了正确的答案。谢谢...
  • @sahleen - 我从未使用过(或知道)ALL。 +1 教我一个新技巧。
猜你喜欢
  • 2020-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 2015-05-02
相关资源
最近更新 更多