将更新与select语句结合使用

时间:2014-07-18 19:14:00

标签: sql sql-server

我正在尝试根据select语句返回的结果更新表中的列。不知道如何将两者结合起来。基本上希望在MemberInstanceInfo表中将IsActive列更新为一个,以获取在SELECT语句中返回的结果。我在SQL Server中这样做。

update xG_v341_GISync.dbo.tSTG_MemberInstanceInfo
Set IsActive = 1

SELECT MIN(M.GICMembID) AS GICMembID, M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber 
FROM xG_v341_GICD.dbo.tCD_MemberInfo M
      INNER JOIN (
                        SELECT LastName, FirstName, CONVERT(varchar(10), Date_Birth, 112) AS DOB, COUNT(*) AS Ct
                        FROM xG_v341_GICD.[dbo].tCD_MemberInfo
                        GROUP BY FirstName, LastName, Date_Birth
                        HAVING count(*)>1
                        )  G
            ON M.LastName = G.LastName
            AND M.FirstName = G.FirstName
            AND M.Date_Birth = G.DOB
      LEFT JOIN xG_v341_GIWeb.dbo.tCM_CarePlan CP
            ON M.GICMembID = CP.GICMembID
      JOIN xG_v341_GISync.dbo.tSTG_MemberInstanceInfo MII
            ON M.HP_Memb_UniqueID = MII.HP_Memb_UniqueID
WHERE CP.GICMembID IS NULL
GROUP BY M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber
ORDER BY M.LastName, M.FirstName

3 个答案:

答案 0 :(得分:0)

根据我所看到的情况,并假设GICMembID是两组之间的参考值,这就是我接近它的方式。

设置CTE(ActiveMembers),仅返回您要“激活”的记录。由于更新只需要GICMembID,因此您可以/应该从CTE中的select中删除其余值。一旦CTE返回正确的结果,请将其加回tSTG_MemberInstanceInfo并转换为更新。

;WITH ActiveMembers 
AS 
(
SELECT MIN(M.GICMembID) AS GICMembID, M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber 
FROM xG_v341_GICD.dbo.tCD_MemberInfo M
      INNER JOIN (
                        SELECT LastName, FirstName, CONVERT(varchar(10), Date_Birth, 112) AS DOB, COUNT(*) AS Ct
                        FROM xG_v341_GICD.[dbo].tCD_MemberInfo
                        GROUP BY FirstName, LastName, Date_Birth
                        HAVING count(*)>1
                        )  G
            ON M.LastName = G.LastName
            AND M.FirstName = G.FirstName
            AND M.Date_Birth = G.DOB
      LEFT JOIN xG_v341_GIWeb.dbo.tCM_CarePlan CP
            ON M.GICMembID = CP.GICMembID
      JOIN xG_v341_GISync.dbo.tSTG_MemberInstanceInfo MII
            ON M.HP_Memb_UniqueID = MII.HP_Memb_UniqueID
WHERE CP.GICMembID IS NULL
GROUP BY M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber
ORDER BY M.LastName, M.FirstName
)

SELECT *
--update T Set IsActive = 1
FROM xG_v341_GISync.dbo.tSTG_MemberInstanceInfo T
JOIN ActiveMembers A 
   ON T.GICMembID = A.GICMembID

将其作为选择运行,如果它返回正确的结果集,您可以切换到更新(注释掉)。

如果需要,您可以根据需要添加AND T.firstname=A.firstname等,以便正确匹配tSTG_MemberInstanceInfo表格。

答案 1 :(得分:0)

JOIN更新的基本语法是:

UPDATE a
SET a.col1 = b.col1
FROM TableA a
JOIN TableB b
    ON a.col1 = b.colx
WHERE --optional criteria

这适用于您的情况:

UPDATE  a
SET a.IsActive = 1
FROM xG_v341_GISync.dbo.tSTG_MemberInstanceInfo a
JOIN (  SELECT *,ROW_NUMBER() OVER(PARTITION BY M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber  ORDER BY  M.GICMembID) RN
        FROM xG_v341_GICD.dbo.tCD_MemberInfo M
                INNER JOIN (
                                SELECT LastName, FirstName, CONVERT(varchar(10), Date_Birth, 112) AS DOB, COUNT(*) AS Ct
                                FROM xG_v341_GICD.[dbo].tCD_MemberInfo
                                GROUP BY FirstName, LastName, Date_Birth
                                HAVING count(*)>1
                                )  G
                    ON M.LastName = G.LastName
                    AND M.FirstName = G.FirstName
                    AND M.Date_Birth = G.DOB
                LEFT JOIN xG_v341_GIWeb.dbo.tCM_CarePlan CP
                    ON M.GICMembID = CP.GICMembID
                JOIN xG_v341_GISync.dbo.tSTG_MemberInstanceInfo MII
                    ON M.HP_Memb_UniqueID = MII.HP_Memb_UniqueID
        WHERE CP.GICMembID IS NULL
      ) b
ON a.GICMembID = b.GICMembID
 AND a.Firstname = b.Firstname
 AND a.lastname = b.lastname
 AND a.DOB = b.DOB
WHERE RN = 1

整个事情可能会被重构,但如果没有额外的熟悉就很难筛选出来。我从MIN()切换到ROW_NUMBER(),这样我就可以返回JOIN所需的所有字段,而无需额外的子查询。

答案 2 :(得分:0)

如果没有关于架构的其他信息,这是我能想到的最好的信息。在执行更新之前运行select查询以进行验证。

SELECT UpdateTable.*
--UPDATE UpdateTable SET isActive = 1
FROM 
(SELECT MIN(M.GICMembID) AS GICMembID, M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber 
FROM xG_v341_GICD.dbo.tCD_MemberInfo M
  INNER JOIN (
                    SELECT LastName, FirstName, CONVERT(varchar(10), Date_Birth, 112) AS DOB, COUNT(*) AS Ct
                    FROM xG_v341_GICD.[dbo].tCD_MemberInfo
                    GROUP BY FirstName, LastName, Date_Birth
                    HAVING count(*)>1
                    )  G
        ON M.LastName = G.LastName
        AND M.FirstName = G.FirstName
        AND M.Date_Birth = G.DOB
  LEFT JOIN xG_v341_GIWeb.dbo.tCM_CarePlan CP
        ON M.GICMembID = CP.GICMembID
  JOIN xG_v341_GISync.dbo.tSTG_MemberInstanceInfo MII
        ON M.HP_Memb_UniqueID = MII.HP_Memb_UniqueID
WHERE CP.GICMembID IS NULL
GROUP BY M.LastName, M.FirstName, M.FullName, M.Date_Birth, CP.CaseNum, CP.CaseNumber)   AggTable
INNER JOIN xG_v341_GICD.dbo.tCD_MemberInfo LookupupTable on 
  LookupupTable.GICMembID = AggTable.GICMembID AND LookupupTable.LastName =   AggTable.LastName AND  LookupupTable.FirstName = AggTable.FirstName AND LookupupTable.Date_Birth = AggTable.Date_Birth
INNER JOIN xG_v341_GISync.dbo.tSTG_MemberInstanceInfo UpdateTable ON LookupupTable.HP_Memb_UniqueID = UpdateTable.HP_Memb_UniqueID