【问题标题】:Replicating VBA solution in SQL在 SQL 中复制 VBA 解决方案
【发布时间】:2019-01-18 16:59:48
【问题描述】:

我有一个 SQL 查询,它为我提供“输出之前”图片中的输出。
第 5 列,如果本质上在 column1 上为 column1 中的项目执行 countif,类似于 Excel。
我想添加一些代码/子查询,以便输出变得像“输出后”图片。

有人知道我该怎么做吗?
我可以用 VBA 在 excel 中做到这一点,但我无法理解如何在 SQL 中做到这一点。

之前的输出

输出后

【问题讨论】:

  • 在询问数据库问题以说明您正在使用的数据库类型时始终提供帮助。
  • Microsoft SQL 服务器管理工​​作室
  • 这是您用来访问数据库的软件。不是数据库/版本。
  • SQL Server 17。抱歉。
  • 如果column2 中的Dave 有不同的值,输出应该是什么样子?

标签: sql sql-server vba transpose countif


【解决方案1】:

由于您使用的是 SQL Server 2017,因此您可以通过 STRING_AGG 获得所需的内容:

select column1, column2, string_agg(column3, '&') as column3, column4
from outputbefore
group by column1, column2, column4

【讨论】:

    【解决方案2】:

    您希望将多行连接成一个值。您的选项取决于您的 SQL Server 版本。在旧版本(我认为是 2005+)中,您必须使用痛苦的 XML 程序。在你的服务器上运行它,你会看到它是如何工作的,但我会留给你来计算你的数据的查询:

    SELECT  STUFF( 
         (SELECT    ', <' + name + '>'
          FROM      sys.databases
          WHERE     database_id > 4
          ORDER BY  name
            FOR   XML PATH('') ,
                      ROOT('MyString') ,
                      TYPE 
         ).value('/MyString[1]', 'varchar(max)'), 1, 2, '') AS namelist;
    

    从 SQL 2017 开始,您可以使用 STRING_AGG 函数,解释为 here

    【讨论】:

      【解决方案3】:

      正如我所见,这是一个字符串连接问题。我使用替换来处理 XML 中的字符 &。

      select a.col1, Col3=replace(stuff((SELECT '#' + b.col3 AS 'data()'
      FROM OutputBefore) b 
      where b.Col1=a.Col1
      FOR XML PATH('')),1,1,''),'#','&')
      from (select distinct Col1 from OutputBefore) a;
      

      【讨论】:

        【解决方案4】:

        正如 forpas 和 Russell 所述,从 SQL 2017 开始,您可以使用 STRING_AGG 函数。

        对于 SQL 2008+ 回过头来看看:

        How Stuff and 'For Xml Path' work in Sql Server

        在您的情况下,您希望分隔符为“&”,这将由于 XML 特殊字符而导致 FOR XML PATH 出现问题。所以你需要转义 XML 特殊字符,例如:

        DECLARE @TableA TABLE (Col1 NVARCHAR(10), Col2 INT, Col3 NVARCHAR(10), Col4 
        
        NVARCHAR(10), Col5 INT)
        
        INSERT INTO @TableA (Col1, Col2, Col3, Col4, Col5)
        VALUES  ('Dave'     , 24    , 'house'   , 'married'     , 2)
            ,   ('Dave'     , 24    , 'car'     , 'married'     , 2)
            ,   ('Bob'      , 32    , 'House'   , 'single'      , 1)
            ,   ('George'   , 12    , 'house'   , 'divorced'    , 1)
        
        SELECT
                t2.Col1
            ,   t2.Col2
            ,   STUFF   (   (   SELECT '&' + Col3 -- Adding '&' as delimited
                                FROM @TableA t1
                                WHERE t1.Col2 = t2.Col2
                                FOR XML PATH (''), TYPE
                            ).value('.', 'VARCHAR(MAX)'),1,1,''-- To escape special characters
                        ) AS Col3
            ,   t2.Col4
        FROM @TableA AS t2
        
        GROUP BY    t2.Col1
                ,   t2.Col2
                ,   t2.Col4
        

        【讨论】:

          猜你喜欢
          • 2010-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-05
          • 2012-11-30
          相关资源
          最近更新 更多