PostgreSQL,高级交换

PostgreSQL,高级交换,postgresql,Postgresql,我得到了一些关于交换同一表格行中某些数据的帮助。 不幸的是,我无法在实践中应用这些解决方案,因为我代表的问题太弱,所以提供的解决方案无法获得预期的结果。 为此,我改进了示例,使其非常易于使用,同时更可能尝试我的具体情况,希望这篇文章不会被视为重复或冒犯 创建表: DROP TABLE IF EXISTS kalksad1; CREATE TABLE kalksad1( kalk_id int PRIMARY KEY, brkalk integer, brred

我得到了一些关于交换同一表格行中某些数据的帮助。
不幸的是,我无法在实践中应用这些解决方案,因为我代表的问题太弱,所以提供的解决方案无法获得预期的结果。
为此,我改进了示例,使其非常易于使用,同时更可能尝试我的具体情况,希望这篇文章不会被视为重复或冒犯

创建表:

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值

以下是两个提供的解决方案,可作为参考。
如果这两种解决方案都能起作用,那么它们都是有用的。
第一个原因是,它可以交换行,而不管顺序和距离如何;第二个原因是,它只交换最常见的第一行,即上面的行或下面的行。 第二种解决方案的问题是,我不知道它交换了什么,但交换了第一行和最后一行,而不是第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;
我希望有人修复上面的查询,使其根据所描述的需求变得可行,或者提供可用于这种交换的新解决方案

多亏了Roman和wildplasser我得到了这个

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
Private Function swap_行(ByVal doc_num为整数,ByVal src_行为整数,ByVal dest_行为整数)为整数
受影响的Dim为整数=0
作为NpgsqlConnection=getConnection()的Dim conn
Dim t作为NpgsqlTransaction=conn.BeginTransaction()
使用cmd作为新的NpgsqlCommand(_
“更新”&mykalksaddable&“作为dst设置brred=src.brred”&_
“从”&mykalksaddable&“作为src”&_
“其中(src.brkalk=“&doc_num.ToString&”)和_
“和dst.brkalk=“&doc_num.ToString&”_
“和dst.brred IN(“&src_row.ToString&”、“&dest_row.ToString&”)和”_
“和src.brred IN(”&src_row.ToString&“,“&dest_row.ToString&”)和”_
“和src.kalk_id dst.kalk_id”,康涅狄格州)
infected=CInt(cmd.ExecuteNonQuery())
cmd.Dispose()
终端使用
如果受影响=2,则t.Commit()
t、 处置
康涅狄格州关闭
康涅狄格州
返回受影响
端函数
私有子DataGridView2U KeyDown(ByVal sender作为对象,ByVal e作为System.Windows.Forms.KeyEventArgs)处理DataGridView2.KeyDown
如果e.Control和e.KeyCode=Keys.Left,则
交换行(kalkbr,选定行,选定行-1)
刷新列表(kalkbr)
如果结束
如果e.Control和e.KeyCode=键,则为
交换行(kalkbr、选定行、选定行+1)
刷新列表(kalkbr)
如果结束

…等…

对于第一个,您必须在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;
将kalksad1更新为dst集
brred=src.brred
来自kalksad1,作为src
哪里
src.brkalk=2和dst.brkalk=2和
dst.brred在(2,3)和
src.brred in(2,3)和
src.kalk_id dst.kalk_id;


我认为第二个太复杂了,我创建它的时候,我认为您想用准确的ID交换行和下一个

可能是因为我解释得太糟糕了。但是这个真的很震撼!!感谢您修复它,并在经过几天的努力后给我最终的解决方案。请注意,如果有N=5条brkak=2的记录,则有5条!可能的排列;这四个!是精神错乱(IIRC)如果我的数学正确,可能的配对数是10(只有两对+一个可能)。意图还不清楚:你是想要一个完全的混乱还是仅仅交换一些对?对不起,乔普,我不完全理解你,但我只是想交换(如上所述),人们能很好地解决我。现在我添加了有问题的NET解决方案和用法。非常优雅。我觉得你想要的不仅仅是交换两行(交换意味着正好两个项目)。如果您想更新整个“块”记录的制表顺序,且brkalk=2,请参见以下答案(也是由wildplasser提供):我在这里得到了我想要的,但您提供的链接非常有趣。我很快就会需要这些作为参考。谢谢
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
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;