【问题标题】:How to Toggle between two values from table rows in Sql如何在Sql中的表行中的两个值之间切换
【发布时间】:2016-12-03 22:15:22
【问题描述】:

我有一个表名[NavBar],其中包含这些列:

Id [int]
Name [nvarchar]
DisplayOrder [int]

样本数据:

Id   Name   DisplayOrder
---------------------------
 1   Home        1
 2   Products    2
 3   Contact     3
 4   Career      4

我想编写一个查询来更新两行之间的DisplayOrder,其 displayOrder 是给定行的下一个更高的显示顺序值。

例如Contact = 4, Career = 3

预期输出:

1  Home      1
2  Products  2
3  Contact   4
4  Career    3

如何执行更新操作以在两个并发行的两行显示顺序之间切换(按 Displayorder 排序)?

输入参数:仅一行的Id

【问题讨论】:

  • 输入参数应该是行的ID和要显示的位置吧?
  • 我的意思是如果输入参数 Id = 3(即联系人),那么我想切换下一个显示顺序行(即职业,即 4)
  • “输入参数:仅一行的ID”是什么意思??
  • 我的意思是id只指定选择和更新。 @Krishnraj

标签: sql sql-server sql-server-2008 sql-server-2005 sql-server-2012


【解决方案1】:

您需要从输入和下一条记录中获取 Displayorder
比你可以更新它。 它有点复杂,但我测试过它可以工作。
当 DisplayOrder 中有间隙时,这样您也可以避免麻烦。

declare @InputID int = 3
declare @DisplayOrderInput int
declare @ID int
declare @DisplayOrder int

select @DisplayOrderInput = DisplayOrder from NavBar where ID = @InputID

select top 1
       @ID = ID,
       @DisplayOrder = DisplayOrder
from   NavBar
where  DisplayOrder > (select DisplayOrder from NavBar where ID = @InputID)
order by DisplayOrder

update NavBar set DisplayOrder = @DisplayOrder where ID = @InputID
update NavBar set DisplayOrder = @DisplayOrderInput where ID = @ID

select * from NavBar

【讨论】:

    【解决方案2】:

    试试这样的:

    UPDATE NavBar  
    SET     DisplayOrder =  CASE  
                            WHEN DisplayName  = @row1 THEN (select DipslayOrder from NavBar where DisplayName = @row2)  
                            WHEN DisplayName  = @row2 THEN (select DipslayOrder from NavBar where DisplayName = @row1) 
                            END 
    WHERE   DisplayName IN (@row1, @row2);
    

    希望这对你有用。

    【讨论】:

    • 如何执行这个查询? @row1、@row2 或 DidplayName 的值是什么?
    【解决方案3】:
        Try with this.. For any id it will work :
    
    DECLARE @INPUT INT=3 
    
    UPDATE A 
    SET    A.DISPLAYORDER = B.DISPLAYORDER 
    FROM   #TEMP A 
           INNER JOIN (SELECT ID, 
                              NAME, 
                              CASE 
                                WHEN ID = @INPUT THEN DISPLAYORDER + 1 
                                WHEN ID = @INPUT + 1 THEN DISPLAYORDER - 1 
                                ELSE DISPLAYORDER 
                              END DISPLAYORDER 
                       FROM   #TEMP)B 
                   ON A.ID = B.ID    
    
    
        Output :
    
        ID  NAME    DISPLAYORDER 
        1   Home        1
        2   Products    2
        3   Contact     4
        4   Career      3
    

    【讨论】:

      【解决方案4】:

      试试这个-

      -- 1) Get Current row's displayorder and Next Row's id in Temp table
      SELECT nb1.DisplayOrder, nb2.id 
      into #TempNavBar
      FROM [NavBar] nb1
      INNER JOIN [NavBar] nb2 ON nb1.id = nb2.id - 1
      WHERE nb1.Id = 3
      
      -- 2) Update Actual table by using Self join on Next row
      UPDATE nb1
          SET nb1.DisplayOrder = nb2.DisplayOrder
      FROM [NavBar] AS nb1
      INNER JOIN [NavBar] AS nb2 ON nb1.id = nb2.id - 1
      WHERE nb1.Id = 3
      
      -- 3). Update Actual table by joining it with temp table
      UPDATE nb1
          SET nb1.DisplayOrder = tmp2.DisplayOrder
      FROM [NavBar] AS nb1
      INNER JOIN #TempNavBar AS tmp2 ON nb1.id = tmp2.id
      
      -- Cleanup operation
      DROP TABLE #TempNavBar
      

      我在这里所做的是将 NavBar 表与其自身连接,但在下一行 id 上并获取当前行的 DisplayOrder 列和下一行的 id 列值并将其插入到临时表中。

      在第二个查询中,我用下一行的值更新了当前行的displayOrder 值。

      在第三个查询中,我通过将 [NavBar] 表与临时表连接起来,使用临时表 DisplayOrder 值更新了 displayOrder 值。

      结果

      Id  Name    DisplayOrder
      ------------------------
      1   Home        1
      2   Products    2
      3   Contact     4
      4   Career      3
      

      【讨论】:

        猜你喜欢
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        • 2022-01-17
        • 2013-06-06
        • 2023-01-05
        • 2012-06-22
        • 2023-02-07
        • 1970-01-01
        相关资源
        最近更新 更多