使用CROSS APPLY的一栏以上 [英] Using CROSS APPLY for more than one column

查看:194
本文介绍了使用CROSS APPLY的一栏以上的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用SQL Server的第3天.

Day #3 with SQL Server.

我正在尝试将2列定界数据合并为一个表值函数的一个输出.这是我的数据:

I am trying to combine 2 columns of delimited data into one output from a Table Valued Function. Here is my data:

我希望以以下格式处理数据并将其放入表格中:

I would like the data to be processed and placed into a table in the following format:

我目前正在尝试使用此CROSS APPLY TSQL语句,但是我不知道自己在做什么.

I am currently trying to use this CROSS APPLY TSQL statement, but I don't know what I'm doing.

USE [Metrics]
INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues)
SELECT d.RawKey, c.*, e.*
FROM dbo.tblRawData d
CROSS APPLY dbo.splitstringcomma(d.DelimitedString) c, dbo.splitstringcomma(d.DelimitedValues) e

我对CROSS APPLY的研究具有广泛的背景,我不了解在这种情况下应如何应用它.我是否需要一个带有附加CROSS APPLY的子查询和一个联接来组合两个表值函数的返回值的子查询?

My research on CROSS APPLY has broad context, and I don't understand how it should be applied in this scenario. Do I need a subquery with an additional CROSS APPLY and a join to combine the returns from the two Table Valued Functions?

这是我最初使用的拆分功能(我不记得作者将其归功于这些功能):

Here is the split function I was using originally (I can't remember the author to credit them):

CREATE FUNCTION [dbo].[splitstring] ( @stringToSplit VARCHAR(MAX), @Delimiter CHAR(1))
RETURNS
 @returnList TABLE ([Name] [nvarchar] (500))
AS
BEGIN

 DECLARE @name NVARCHAR(255)
 DECLARE @pos INT

 WHILE CHARINDEX(@Delimiter, @stringToSplit) > 0
 BEGIN
  SELECT @pos  = CHARINDEX(@Delimiter, @stringToSplit)  
  SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1)

  INSERT INTO @returnList 
  SELECT @name

  SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)-@pos)
 END

 INSERT INTO @returnList
 SELECT @stringToSplit

 RETURN
END

修改并编辑修改后的查询

USE [Metrics] 
INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues)
SELECT s.RawKey, s.SplitString, v.SplitValues
FROM (
SELECT d.RawKey, d.DelimitedString,
 c.item SplitString, c.rn
FROM dbo.tblRawData d
CROSS APPLY dbo.splitstring(d.DelimitedString, ',') c
) s

INNER JOIN

(
SELECT d.RawKey, d.DelimitedValues,
 c.item SplitValues, c.rn
FROM dbo.tblRawData d
CROSS APPLY dbo.splitstring(d.DelimitedValues, ',') c
) v
on s.RawKey = v.RawKey
and s.rn = v.rn;

推荐答案

如果我们可以看到您的分割字符串函数,则回答这个问题可能会更容易.我的答案是使用我拥有的拆分功能的版本.

It might be easier to answer this if we could see your split string function. My answer is using a version of my split function that I have.

我将在您的拆分函数中包含一个行号,您可以使用该行号来联接拆分字符串和拆分值.

I would include in your split function a row number that you can use to JOIN the split string and the split values.

分割功能:

CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX), rn int)       
as       
begin      
    declare @idx int       
    declare @slice varchar(8000)   
    declare @rn int = 1 -- row number that increments with each value in the delimited string

    select @idx = 1       
        if len(@String)<1 or @String is null  return       

    while @idx!= 0       
    begin       
        set @idx = charindex(@Delimiter,@String)       
        if @idx!=0       
            set @slice = left(@String,@idx - 1)   
        else       
            set @slice = @String       

        if(len(@slice)>0)  
            insert into @temptable(Items, rn) values(@slice, @rn)       

        set @String = right(@String,len(@String) - @idx)       
        set @rn = @rn +1

        if len(@String) = 0 break       
    end   
return 
end;

然后,如果要拆分多个列,则可以使用类似于以下内容的查询:

Then if you have multiple columns to split, you could use a query similar to the following:

INSERT INTO dbo.tblSplitData(SplitKey, SplitString, SplitValues)
select s.rawkey,
  s.splitstring,
  v.splitvalues
from
(
  SELECT d.RawKey, d.delimitedstring, d.delimitedvalues, 
    c.items SplitString, 
    c.rn
  FROM dbo.tblRawData d
  CROSS APPLY dbo.Split(d.DelimitedString, ',') c
) s
inner join
(
  SELECT d.RawKey, d.delimitedstring, d.delimitedvalues, 
    c.items SplitValues, 
    c.rn
  FROM dbo.tblRawData d
  CROSS APPLY dbo.Split(d.DelimitedValues, ',') c
) v
  on s.rawkey = v.rawkey
  and s.delimitedstring = v.delimitedstring
  and s.rn = v.rn;

请参见带有演示的SQL小提琴

这使用两个子查询来生成拆分值列表,然后使用拆分函数创建的行号将它们连接起来.

This uses two subqueries that generate the list of split values, then they are joined using the row number created by the split function.

这篇关于使用CROSS APPLY的一栏以上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆