简体   繁体   English

在 SQL 中复制 VBA 解决方案

[英]Replicating VBA solution in SQL

I have a SQL query that provides me with the output in the 'Output Before' pic.我有一个 SQL 查询,它为我提供了“输出之前”图片中的输出。
Column 5 if essentially doing a countif on column1 for items in column1, similar to Excel.第5列,如果主要做了countif上COLUMN1在列1项,相似到Excel。
I would like to add some code/sub query, so that the output becomes like the 'Output After' pic.我想添加一些代码/子查询,以便输出变得像“输出之后”图片。

Does anyone have any ideas how I can do this?有没有人有任何想法我怎么能做到这一点?
I can do it in excel with VBA but just cant get my head around how to do it in SQL.我可以用 VBA 在 excel 中做到这一点,但我无法理解如何在 SQL 中做到这一点。

Output Before输出前
输出前

Output After输出之后
输出之后

Since you are using SQL Server 2017 you can get what you want with STRING_AGG :由于您使用的是 SQL Server 2017,您可以通过STRING_AGG获得您想要的:

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

You're looking to concatenate multiple rows into a single value.您希望将多行连接成一个值。 Your options depend on your version of SQL Server.您的选项取决于您的 SQL Server 版本。 In older versions (I think 2005+) you have to use a torturous XML procedure.在旧版本(我认为 2005+)中,您必须使用一个折磨人的 XML 过程。 Run this on your server and you'll see how it works, but I'll leave it to you to work out the query for your data:在你的服务器上运行它,你会看到它是如何工作的,但我会让你来计算你的数据的查询:

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;

As of SQL 2017 you can use the STRING_AGG function, explained here .从 SQL 2017 开始,您可以使用 STRING_AGG 函数, 在此处解释。

As I see this is a string concatenation issue.正如我所见,这是一个字符串连接问题。 I used a replace to handle the character & in XML.我使用替换来处理 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;

As mentioned by forpas and Russell, as of SQL 2017 you're able to use STRING_AGG function.正如 forpas 和 Russell 所提到的,从 SQL 2017 开始,您可以使用 STRING_AGG 函数。

For SQL 2008+ Refer back to this:对于 SQL 2008+,请参考:

How Stuff and 'For Xml Path' work in Sql Server Stuff 和“For Xml Path”如何在 Sql Server 中工作

In your case you want the delimiter to be '&' which will cause a problem with FOR XML PATH due to XML Special character.在您的情况下,您希望分隔符为 '&',这会由于 XML 特殊字符而导致 FOR XML PATH 出现问题。 So you'll want to escape XML Special characters, example:因此,您需要转义 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM