Sql server 使用不同的数据类型联接表

Sql server 使用不同的数据类型联接表,sql-server,join,sql-function,Sql Server,Join,Sql Function,我有以下表格: Orders id int orderName varchar(5000) Communication body varchar(5000) attachment varchar(5000) 订单数据示例: id name 132 ordGD 589 ordPG 6321 ordMF 通信数据示例: body attachment body1 132,589,6321 我想创建一个存储过程,从通信中获取两列{body,Attachment

我有以下表格:

Orders
  id int
  orderName varchar(5000)

Communication
  body varchar(5000)
  attachment varchar(5000)
订单数据示例:

id   name
132  ordGD
589  ordPG
6321 ordMF
通信数据示例:

body    attachment
body1   132,589,6321
我想创建一个存储过程,从通信中获取两列{body,Attachment}

在SP中,输入@attachment varchar5000包含多个引用Orders表的orderid,以逗号分隔


问题:我希望OrderName根据与@Attachment匹配的订单中的Orderid进行排序。对于这种类型的流程,您需要拆分附件列中的数据。我使用类似于此的方法拆分字符串拆分字符串有很多方法,您可以在线搜索其他函数:

CREATE FUNCTION [dbo].[Split](@String varchar(MAX), @Delimiter char(1))       
returns @temptable TABLE (items varchar(MAX))       
as       
begin     
    declare @idx int       
    declare @slice varchar(8000)       

    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) values(@slice)       

        set @String = right(@String,len(@String) - @idx)       
        if len(@String) = 0 break       
    end   
return      

end

如果只想用正确的名称替换附件字段中的值,可以一步使用拆分函数和CTE:

;with cte as (
  select o.id,
    o.name,
    c.body
  from orders o
  left join 
  (
    select c.body, s.items as o_id
    from communications c
    cross apply dbo.split(c.attachment, ',') s
  ) c
    on o.id = c.o_id
)
select distinct c2.body,
  stuff((select distinct ', ' + c1.name
         from cte c1
         where c2.body = c1.body
         for XML path('')),1,1,'') attachment
from cte c2

参见

正如其他人所评论的,正确的解决方案是将数据库模式更改为具有原子字段的规范化模式

当前模式的一个解决方案是首先使用任意一种方法将附件字段拆分为订单号列表。下一步是将结果与id上的Orders表联接以获得结果。第三步是完成任务。有关拆分和联接的说明,请参见提供的链接

以下是执行3个步骤的代码段:

WITH
-- Numbers table for split logic
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3),

-- The join query for step 2
bodyOrders AS
(SELECT body,        
       o1.name orderName
FROM   Numbers AS nums 
INNER JOIN Communication AS valueTable 
ON nums.n <= CONVERT(int, LEN(valueTable.attachment)) 
AND SUBSTRING(N',' + valueTable.attachment, n, 1) = N','
INNER JOIN Orders o1
ON LTRIM(RTRIM(SUBSTRING(valueTable.attachment, nums.n, 
   charindex(N',', valueTable.attachment + N',', nums.n) - nums.n))) = o1.id
)

-- Concatenation logic for step 3
SELECT  body,
stuff( (SELECT ','+ orderName
               FROM bodyOrders b2
               WHERE b2.body = b1.body 
               ORDER BY orderName
               FOR XML PATH(''), TYPE).value('.', 'varchar(5000)')
            ,1,1,'')
       AS orderNumbers
      FROM bodyOrders b1
      GROUP BY body;
对于大型数据集,此代码段并没有提供最佳或高性能的方法。这只是一个例子,说明如果你必须沿着这条路走下去,你会怎么做


.

你的问题真的很难理解。能否提供相关表中列的架构名称和类型以及一些示例输入数据和预期输出数据?不能作为联接完成。将数据拆分并以原子方式存储,而不是将其组合在一起。否则,使用游标读取数据,对其进行解析,并将匹配的订单记录存储在临时表或表变量中。但是不要期望有好的性能。Table:Orders列:orderid列:ordername\u Table:communication列:body列:Attachmentattachment具有orderid,如>1325896321,我想将orderid转换为相应的ordername,如>ordGD、ordPG、ordMF
WITH
-- Numbers table for split logic
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
Numbers AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L3),

-- The join query for step 2
bodyOrders AS
(SELECT body,        
       o1.name orderName
FROM   Numbers AS nums 
INNER JOIN Communication AS valueTable 
ON nums.n <= CONVERT(int, LEN(valueTable.attachment)) 
AND SUBSTRING(N',' + valueTable.attachment, n, 1) = N','
INNER JOIN Orders o1
ON LTRIM(RTRIM(SUBSTRING(valueTable.attachment, nums.n, 
   charindex(N',', valueTable.attachment + N',', nums.n) - nums.n))) = o1.id
)

-- Concatenation logic for step 3
SELECT  body,
stuff( (SELECT ','+ orderName
               FROM bodyOrders b2
               WHERE b2.body = b1.body 
               ORDER BY orderName
               FOR XML PATH(''), TYPE).value('.', 'varchar(5000)')
            ,1,1,'')
       AS orderNumbers
      FROM bodyOrders b1
      GROUP BY body;