web-dev-qa-db-ja.com

SQLはSELECTステートメントを介して複数のフィールドから更新します

これは機能しますが、冗長性を削除したいと思います。 varsを使用する必要がないように、更新を単一のselectステートメントとマージする方法はありますか?

    DECLARE
        @OrgAddress1 varchar,
        @OrgAddress2 varchar,
        @OrgCity varchar,
        @OrgState varchar,
        @OrgZip varchar,
        @DestAddress1 varchar,
        @DestAddress2 varchar,
        @DestCity varchar,
        @DestState varchar,
        @DestZip varchar

    SELECT 
        @OrgAddress1    =   OrgAddress,
        @OrgAddress2    =   OrgAddress2,
        @OrgCity        =   OrgCity,
        @OrgState       =   OrgState,
        @OrgZip         =   OrgZip,
        @DestAddress1   =   DestAddress,
        @DestAddress2   =   DestAddress2,
        @DestCity       =   DestCity,
        @DestState      =   DestState,
        @DestZip        =   DestZip
    FROM 
        ProfilerTest.dbo.BookingDetails 
    WHERE 
        MyID=@MyID

    UPDATE SHIPMENT
    SET
        OrgAddress1     =   @OrgAddress1,
        OrgAddress2     =   @OrgAddress2,
        OrgCity         =   @OrgCity,
        OrgState        =   @OrgState,
        OrgZip          =   @OrgZip,
        DestAddress1    =   @DestAddress1,
        DestAddress2    =   @DestAddress2,
        DestCity        =   @DestCity,
        DestState       =   @DestState,
        DestZip         =   @DestZip
    WHERE 
        MyID2=@ MyID2
38
KellCOMnet

このような何かが動作するはずです(今はテストできません-メモリから):

UPDATE SHIPMENT
SET
  OrgAddress1     = BD.OrgAddress1,
  OrgAddress2     = BD.OrgAddress2,
  OrgCity         = BD.OrgCity,
  OrgState        = BD.OrgState,
  OrgZip          = BD.OrgZip,
  DestAddress1    = BD.DestAddress1,
  DestAddress2    = BD.DestAddress2,
  DestCity        = BD.DestCity,
  DestState       = BD.DestState,
  DestZip         = BD.DestZip
FROM
   BookingDetails BD
WHERE 
   SHIPMENT.MyID2 = @MyID2
   AND
   BD.MyID = @MyID

それは役立ちますか?

55
marc_s

あなたは次の線に沿って何かをすることができるはずです

UPDATE s
SET
    OrgAddress1 = bd.OrgAddress1,
    OrgAddress2 = bd.OrgAddress2,
    ...
    DestZip = bd.DestZip
FROM
    Shipment s, ProfilerTest.dbo.BookingDetails bd
WHERE
    bd.MyID = @MyId AND s.MyID2 = @MyID2

FROMステートメントは(より具体的な結合を使用して)より最適化することができますが、上記の方法でうまくいくはずです。また、この方法で作成すると、UPDATEの変更のプレビューを見ることができますUPDATE s SETを読むSELECT!更新が行われた場合に表示されるデータが表示されます。

6
Joshua Shannon

次を使用できます。

UPDATE s SET
  s.Field1 = q.Field1,
  s.Field2 = q.Field2,
  (list of fields...)
FROM (
  SELECT Field1, Field2, (list of fields...)
  FROM ProfilerTest.dbo.BookingDetails 
  WHERE MyID=@MyID
) q
WHERE s.MyID2=@ MyID2
5
eKek0

更新を使用できます...

何かのようなもの:

出荷セットの更新...出荷内部結合からProfilerTest.dbo.BookingDetailsの...

1
fhranc

シーケンス番号を追加した同様の問題を解決する必要がありました(そのため、親IDでグループ化されたアイテムには、順序を変更できるシーケンスがあります(おそらく、ユーザーは順序を変更して順序を変更できます)。

私の場合、それは患者の保険であり、ユーザーは割り当てられた順序を設定できるので、主キーを使用するだけでは長期的には役に立ちませんが、デフォルトを設定するのには便利です。

他のすべてのソリューションの問題は、特定の集計関数がSELECTの外部で許可されないことです

このSELECTは、新しいシーケンス番号を取得します。

select PatientID,
       PatientInsuranceID, 
       Sequence, 
       Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
from PatientInsurance
order by PatientID, PatientInsuranceID

この更新コマンドは簡単ですが、許可されていません:

update PatientInsurance
set Sequence = Row_Number() over(partition by PatientID order by PatientInsuranceID)

解決したソリューション(私はちょうどそれをやった)、eKek0のソリューションに似ています:

UPDATE PatientInsurance
SET  PatientInsurance.Sequence = q.RowNum
FROM (select PatientInsuranceID, 
             Row_Number() over(partition by PatientID order by PatientInsuranceID) as RowNum
      from PatientInsurance
     ) as q 
WHERE PatientInsurance.PatientInsuranceID=q.PatientInsuranceID 

これにより、一致させる必要があるIDと、そのIDに設定する必要がある値を選択できます。 SELECTの外では動作しないRow_Number()を使用していなかった場合、他のソリューションは問題なかったでしょう。

これが1回の操作であることを考えると、コーディングはまだ単純であり、実行速度は4000行以上に対して十分に高速です。

0
KenF

このように書きます

UPDATE s
SET    OrgAddress1 = bd.OrgAddress1,    OrgAddress2 = bd.OrgAddress2,    
     ...    DestZip = bd.DestZip
--select s.OrgAddress1, bd.OrgAddress1, s.OrgAddress2, bd.OrgAddress2, etc 
FROM    Shipment s
JOIN ProfilerTest.dbo.BookingDetails bd on  bd.MyID =s.MyID2
WHERE    bd.MyID = @MyId 

暗黙的な結合は悪いことなので、この方法は明示的です。コメントアウトしたselect(通常は、古い値と新しい値を更新するフィールドを並べて指定します)を実行して、更新しようとしているものが正確に更新することを確認できます。

0
HLGEM