【问题标题】:Cursors in functions/procedures in SQL ServerSQL Server 函数/过程中的游标
【发布时间】:2012-07-16 12:50:03
【问题描述】:

我想知道在 SQL Server 中是否可以执行以下操作 - 它涉及 光标使用,我不确定 如何 将其放置在函数中或存储过程。

你会推荐什么?

TABLEA 具有以下列:

Column1, Column2

例子

Column1 Column2
------- -------
anna     a
anna     b
ben      b
john     c
john     b
john     a 

column2 中可能的值是:a、b 和 c(对于 Column1 上的某个值没有重复)

创建TABLEB结构:Column1 Column3 Column4 Column5.

  1. 有一个游标循环遍历TABLEA 的所有行
  2. SELECT * FROM TABLEB WHERE Column1 = (cursor row).Column1
  3. 如果之前的选择没有返回任何行, 在 Column1 = (cursor row).Column1 中插入一行到 TABLEB 中,并在 Columns3、4 和 5 上插入 NULL 值。

    如果(从先前选择返回的行)> 0:

    { 如果 TABLEB.Column3 不为空,则使用 (光标行).Column2 更新 TABLEB

    如果 TABLEB.Column4 不为空,则使用(光标行).Column2 更新 TABLEB

    如果 TABLEB.Column5 不为空,则使用 (光标行).Column2 更新 TABLEB }

  4. 结束光标循环

如您所见,我非常清楚自己想要做什么,但对语法或在这种情况下推荐的内容知之甚少。

输出应该在这些步骤之后:

Column1 Column3 Column4 Column5
------  ------- ------- -------
anna    a        b       
ben     b            
john    c        b       a

我最感兴趣的是是否可以使用游标,如果可以,您是否有任何学习语法的提示/教程,您是否建议我将示例集成到过程/函数中?

谢谢!

稍后编辑:

podiluska,我尝试使用枢轴,如下所示:

CREATE VIEW VIEWB
AS SELECT [Column1], 
('Column2') AS [Source],
MAX( CASE Column2 WHEN 'a' THEN Column2 ELSE '' END ) Column3,         
MAX( CASE Column2 WHEN 'b' THEN Column2 ELSE '' END ) Column4,         
MAX( CASE Column2 WHEN 'c' THEN Column2 ELSE '' END ) Column5          
FROM TABLEA
GROUP BY [Column1];
GO 

这种方法的问题在于输出是:

Column1 Column3 Column4 Column5
------  ------- ------- -------
anna    a        b       
ben              b            
john    a        b       c

您会注意到与第一个输出和所需输出的不同。

【问题讨论】:

  • “column2 中的可能值是:a、b 和 c(无重复)”除了您的示例清楚地表明可能存在重复。我认为您的意思是元组 (Column1 Column2) 是唯一的。
  • Mark Byers:对不起,Column1 中的某个值没有重复:anna 不能有 c 两次。在这种情况下,anna 有 a 和 b。
  • 你会推荐什么? - 避免像瘟疫一样的游标!
  • 见下面的编辑,重新:移位列

标签: sql sql-server-2008 cursor


【解决方案1】:

您可以使用光标,但我建议您使用 PIVOT 即:

 select column1, 
      case a when 0 then null else 'a' end,
      case b when 0 then null else 'b' end,
      case c when 0 then null else 'c' end
 from
      TableA as p
 pivot
      (Count(column2) for column2 in ([a],[b],[c]))
 as pt

如果你想移动列,试试这个...

 select column1,
      case when c3 is null then c4 else c3 end c3,
      case when c3 is null then c5 else c4 end c4,
      case when c3 is null then null else c5 end c5
 from
 (
 select column1,
    case when c3 is null then c4 else c3 end c3,
    case when c3 is null then c5 else case when c4 is null then c5 else c4 end end c4,
    case when c3 is null or c4 is null then null else c5 end c5
 from
 (
 select column1, 
    case a when 0 then null else 'a' end c3,
    case b when 0 then null else 'b' end c4,
    case c when 0 then null else 'c' end c5
 from
    #temp as p
 pivot
    (Count(column2) for column2 in ([a],[b],[c]))
 as pt
 ) v
 ) v2

【讨论】:

    【解决方案2】:

    您根本不需要光标。这很容易

    select 
        column1,
        max(case when column2='a' then column2  end) as column1,
        max(case when column2='b' then column2  end) as column2,
        max(case when column2='c' then column2  end) as column3
    from
        table
    group by
        column1
    

    【讨论】:

    • 谢谢,Madhivan,我试过了——请看我问题的最后一部分。这确实是一件很棒的事情但是这种特殊方法对我来说的问题是每一列只有一个值。我在问题中解释了“我想要的输出”和应用“旋转”的输出之间的区别。
    猜你喜欢
    • 1970-01-01
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多