【问题标题】:Loop through columns SQL循环遍历列 SQL
【发布时间】:2009-03-30 14:08:11
【问题描述】:

我正在寻找一种方法来循环遍历表的列以生成如下所述的输出。

表格是这样的:

ID 名称 OPTION1 OPTION2 OPTION3 OPTION4 OPTION5 1 我的名字 1 1 0 1 1 0 2 我的名字2 0 0 1 0 0

输出看起来像这样:

我的名字 1 -> 选项 1、选项 3、选项 4 我的名字 2 -> 选项 3

任何这样做的方向都将不胜感激。否则,我想我将不得不使用游标或临时表......数据库引擎是 MSSQL。我在数据库级别进行格式化的原因是将其输出提供给有限的可编程环境。

更新:输出可以是任何形式,一个字符串或多行字符串。

更新:是否可以通过使用 @str = @str + ... 构建字符串来实现这一点?

更新:我更改了输出...这应该更容易。

谢谢!

【问题讨论】:

  • 你有固定的列数吗? (也是“Option4 -> MyName1”?)
  • 嗨,Ian,是的,假设我们有固定数量的列。
  • 我认为它不清楚输出应该是什么。你想拿一张桌子并生成文本字符串吗? “数据透视表”解决方案将生成结果集或另一个表。
  • 我又更新了。输出可以是任何形式,作为一个字符串或多行字符串。

标签: sql sql-server csv loops


【解决方案1】:

好吧,在已知列数的情况下,您可以这样做:

SELECT  
  MyName + " ->"
  + case OPTION1 when 1 then ' OPTION1' else '' end
  + case OPTION2 when 1 then ' OPTION2' else '' end
  + ...
FROM
 Table

如果在创建查询时列是未知的 - 我可能仍然会使用一些动态创建的 SQL。优点是代码可能做你想做的,而且非常简单。

【讨论】:

    【解决方案2】:

    您可能想看看 PIVOT Tables。

    【讨论】:

    • 对,数据透视表应该是可用的。检查是否有其他关于我不知道的方法的新想法。
    【解决方案3】:

    由于您没有详细说明您为什么希望能够做到这一点的具体需求,我无法确定,但通常当我看到此类问题时,我会想到两件事:

    1. 您需要规范化您的数据库。也许“Option1”、“Option2”等没有共同点,但它们也很有可能是您表中的重复组。

    2. 在应用程序的显示层处理显示问题 - 即前端,而不是数据库。

    正如我所说,由于某些特定原因,这些可能不适用于您的情况,但从我阅读您的问题来看,似乎是这样。

    【讨论】:

    • 对,汤姆。我尝试在数据库级别进行格式化的原因是能够直接在我没有太多脚本灵活性的报告中提供输出。
    • 是的,这将是这种事情变得必要的情况之一。继续。 ;)
    【解决方案4】:

    您可以使用系统目录构建动态语句:

    http://msdn.microsoft.com/en-us/library/ms189082.aspx

    【讨论】:

      【解决方案5】:

      如果使用数据透视表,您必须确保所有“选项”列具有相同的数据类型和长度。

      我建议以下答案:


      IF NOT EXISTS( SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME      
       = 'TABLE1' ) 
      create table table1
      (
         name nvarchar(50),       
         colvalue nvarchar(50)
      )
      else
        truncate table table1
      
      declare @table nvarchar(50)
      set @table = 'yourtable'
      
      declare @column table
      (
         ID integer identity,
         colname nvarchar(20)
      )
      
      
      insert into @column
      SELECT c.name FROM sys.tables t 
      JOIN sys.columns c ON t.Object_ID = c.Object_ID 
      WHERE t.Name = @table 
      and c.name in ('Option1','Option2','Option3','Option4','Option5')
      
      declare @minID integer, @maxID integer
      declare @cmd nvarchar(max)  
      declare @col nvarchar(20)
      declare @SQLStr nvarchar(max)
      
      select @minID = MIN(ID), @maxID= MAX(ID)
      from @column
      
      while @minID <= @maxID
      begin
          select @col = colname
          from @column
          where ID = @minID
      
          set @SQLStr =    
          'insert into table1 (name, colvalue)
          select name,' + @col + '
          from ' + @table + ' 
          where ' + @col + ' <> 0'    
      
          exec(@SQLStr)
      
          set @minID = @minID + 1
      end
      
      select distinct name, STUFF(
      (SELECT  ',' + a.colvalue  AS [text()]
      from Table1  a
      where a.name = b.name
      Order by a.colvalue
      for xml PATH('')),1,1,''    ) AS Comments_Concatenated
      from Table1 b
      group by name, colvalue
      ORDER BY name
      

      您只需在插入@column 之前输入您的表名和您需要的列的列表来修改@table。

      无论你是什么数据类型,它都能正常工作。

      【讨论】:

        【解决方案6】:
        猜你喜欢
        • 1970-01-01
        • 2014-09-27
        • 1970-01-01
        • 1970-01-01
        • 2018-12-06
        • 1970-01-01
        • 2023-03-19
        • 2017-10-19
        • 2013-06-22
        相关资源
        最近更新 更多