0

ここで、同じテーブルの行にある特定のデータを交換する際の助けが得られます。
残念ながら、問題が弱すぎるため、これらのソリューションを実際に適用することはできません。提供されたソリューションでは、期待される結果が得られません。
そのために、私は例を改善し、非常に使いやすくすると同時に、この投稿が重複したり攻撃的なものとして扱われないことを願って、私の具体的な状況をより可能性の高いものにします.

テーブルの作成:

DROP TABLE IF EXISTS kalksad1;

CREATE TABLE kalksad1(
kalk_id     int PRIMARY KEY,
brkalk      integer, 
brred       integer, 
description text
);

INSERT INTO kalksad1 VALUES
  (12, 2, 5, 'text index 12 doc 2 row 5'),
  (26, 2, 1, 'text index 26 doc 2 row 1'),
  (30, 2, 2, 'text index 30 doc 2 row 2'),
  (32, 4, 1, 'text index 32 doc 4 row 1'),
  (36, 1, 1, 'text index 36 doc 1 row 1'),
  (37, 1, 2, 'text index 37 doc 1 row 2'),
  (38, 5, 1, 'text index 38 doc 5 row 1'),
  (39, 5, 2, 'text index 39 doc 5 row 2'),
  (42, 2, 3, 'text index 42 doc 2 row 3'),
  (43, 2, 4, 'text index 43 doc 2 row 4'),
  (46, 3, 1, 'text index 46 doc 3 row 1'),
  (47, 3, 2, 'text index 47 doc 3 row 2');

必要なもの?

同じ「brkalk」の列「brred」でのみ数値を交換するクエリを作成するには。
'brred' と 'brkalk' は両方とも、プログラムを通じて外部で定義されます。
例として、brkalk=2、brred=3 を使用します。
つまり、brkalk=2 の場合、行でのみ brred 値を交換する必要があります。

ここでは、参照として使用できる 2 つの提供されたソリューションを示します。
どちらのソリューションも、機能する場合に役立ちます。
1 つ目は、順序や距離に関係なく行を交換できるため、2 つ目は、最も一般的なニーズである上または下の最初の行のみと交換するためです。2番目の解決策の問題は、何をスワップするのかわからないが、行3と2ではなく最初と最後の行を交換することです。
これは修復する必要があります。

新しい状況では最初のクエリがまったく機能しないので、誰かがそれを修正してくれるといいのですが。これは、行 4 と 1 をスワップするなど、外部引数による「方向」に関係なく行を交換するのに役立ちます。

明確にするために、「スワップ行」と言うとき、同じ「brkalk」に属する「brred」列の値のみをスワップすることを意味します(この場合は2)。

最初のクエリ:

    UPDATE kalksad1 dst 
        SET brred=src.brred 
        FROM kalksad1 src 
        WHERE src.brkalk='2' 
        AND dst.kalk_id IN(2,3) 
        AND src.kalk_id IN(2,3) 
        AND dst.kalk_id <> src.kalk_id;

2 番目のクエリ

    WITH cte1 AS (
        SELECT row_number() OVER(ORDER BY kalk_id ASC) AS row_num, kalk_id, brred 
        FROM kalksad1
        WHERE kalk_id >= 3 ORDER BY kalk_id LIMIT 2
        ) 
    UPDATE kalksad1 AS t 
        SET brred = COALESCE(c2.brred, t.brred) 
        FROM cte1 AS c1 
        LEFT OUTER JOIN cte1 AS c2 ON c2.row_num <> c1.row_num 
        WHERE t.kalk_id = c1.kalk_id AND brkalk='2';

データを表示するには、次を使用するのが最適です。

SELECT * FROM kalksad1 WHERE brkalk='2' ORDER BY brred;

説明されたニーズに従って実行可能になるように上位のクエリを修正するか、その種のスワッピングに使用できる新しいソリューションを提供してください。

だから、ローマンとワイルドプラッサーのおかげで私はこれを手に入れました...

Private Function swap_row(ByVal doc_num As Integer, ByVal src_row As Integer, ByVal dest_row As Integer) As Integer

    Dim affected As Integer = 0
    Dim conn As NpgsqlConnection = getConnection()
    Dim t As NpgsqlTransaction = conn.BeginTransaction()

    Using cmd As New NpgsqlCommand( _
        "UPDATE " & myKalkSadTable & " AS dst SET brred = src.brred " & _
        "FROM " & myKalkSadTable & " AS src " & _
        "WHERE(src.brkalk = " & doc_num.ToString & ") " & _
        "AND dst.brkalk = " & doc_num.ToString & " " & _
        "AND dst.brred IN (" & src_row.ToString & "," & dest_row.ToString & ") " & _
        "AND src.brred IN (" & src_row.ToString & "," & dest_row.ToString & ") " & _
        "AND src.kalk_id <> dst.kalk_id", conn)

        affected = CInt(cmd.ExecuteNonQuery())
        cmd.Dispose()
    End Using

    If affected = 2 then t.Commit()
    t.Dispose()
    conn.Close()
    conn.Dispose()

    Return affected
End Function

Private Sub DataGridView2_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DataGridView2.KeyDown

    If e.Control And e.KeyCode = Keys.Left Then
        swap_row(kalkbr, selected_row, selected_row - 1)
        Refreshlist(kalkbr)
    End If

    If e.Control And e.KeyCode = Keys.Right Then
        swap_row(kalkbr, selected_row, selected_row + 1)
        Refreshlist(kalkbr)
    End If

...など...

4

1 に答える 1

1

まず、dst と src の両方で brkalk をフィルタリングする必要があります。

update kalksad1 as dst set
    brred = src.brred 
from kalksad1 as src 
where
    src.brkalk = 2 and dst.brkalk = 2 and
    dst.brred in (2,3) and
    src.brred in (2,3) and
    src.kalk_id <> dst.kalk_id;

SQL フィドルのデモ

2つ目は複雑すぎると思います。正確なIDと次の行を入れ替えたいと思ったときに作成しました

于 2013-08-15T10:44:27.483 に答える