CategoryTable
Code Name
1 Food
2 Non-Food
现有表格包含类别列表,例如,我有两个只有食物和非食物
作为挑战,我正在为租户分配类别或类别(多次转让,因为有些租户被归类为食品和非食品)。我曾经将Tenant和Code插入到创建此输出的新表中
TenantAssignTable
Tenant Code
Tenant1 1,2
Tenant2 1
我需要做的是将TenantAssingTable加载到包含CategoryCode名称的gridview,就像这样
所需输出
Tenant CCode Name
Tenant1 1,2 Food,Non-Food
Tenant2 1 Food
我在代码中使用了内部联接,但这是有限的,因为我在代码列中有一串组合代码。
Select a.tenant, a.ccode, b.name
from TenantAssignTable a inner join CategoryTable b
on a.CCode = b.code
无论如何都要实现这种输出吗?我知道这在SQL编码中是不寻常的,但这就是所需的输出所关注的挑战,以及为单个租户多次分配类别的需求。
提前致谢!
答案 0 :(得分:2)
想想简单;
您可以使用LIKE
和XML PATH
DECLARE @CategoryTable TABLE (Code VARCHAR(50), Name VARCHAR(50))
INSERT INTO @CategoryTable
VALUES
('1', 'Food'),
('2', 'Non-Food')
DECLARE @TenantAssignTable TABLE (Tenant VARCHAR(50), Code VARCHAR(50))
INSERT INTO @TenantAssignTable
VALUES
('Tenant1', '1,2'),
('Tenant2', '1')
SELECT
T.Tenant ,
T.Code,
STUFF(
(SELECT
',' + C.Name
FROM
@CategoryTable C
WHERE
',' + REPLACE(T.Code, ' ', '') + ',' LIKE '%,' + C.Code + ',%'
FOR XML PATH('')
), 1, 1, '') A
FROM
@TenantAssignTable T
结果:
Tenant Code A
--------------- ------------ ---------------
Tenant1 1,2 Food,Non-Food
Tenant2 1 Food
答案 1 :(得分:0)
您可以使用一些XML转换:
DECLARE @x xml
SELECT @x = (
SELECT CAST('<t name="'+a.tenant +'"><a>'+REPLACE(a.code,',','</a><a>') +'</a></t>' as xml)
FROM TenantAssignTable a
FOR XML PATH('')
)
;WITH cte AS (
SELECT t.v.value('../@name','nvarchar(max)') as Tenant,
t.v.value('.','int') as CCode,
ct.Name
FROM @x.nodes('/t/a') as t(v)
INNER JOIN CategoryTable ct
ON ct.Code = t.v.value('.','int')
)
SELECT DISTINCT
c.Tenant,
STUFF((SELECT ','+CAST(CCode as nvarchar(10))
FROM cte
WHERE c.Tenant = Tenant
FOR XML PATH('')
),1,1,'') as CCode,
STUFF((SELECT ','+Name
FROM cte
WHERE c.Tenant = Tenant
FOR XML PATH('')
),1,1,'') as Name
FROM cte c
输出:
Tenant CCode Name
Tenant1 1,2 Food,Non-Food
Tenant2 1 Food
第一部分(定义{{1}}变量)将使您的表成为这种XML:
@x
然后在CTE部分,我们将XML与类别表联系起来。毕竟在FOR XML PATH的帮助下从CTE获取数据。
答案 2 :(得分:0)
创建如下所示的函数,该函数从分离的值
返回表CREATE FUNCTION [dbo].[fnSplit]
(
@String NVARCHAR(4000),
@Delimiter NCHAR(1)
)
RETURNS TABLE
AS
RETURN
(
WITH Split(stpos,endpos)
AS(
SELECT 0 AS stpos, CHARINDEX(@Delimiter,@String) AS endpos
UNION ALL
SELECT endpos+1, CHARINDEX(@Delimiter,@String,endpos+1)
FROM Split
WHERE endpos > 0
)
SELECT 'Id' = ROW_NUMBER() OVER (ORDER BY (SELECT 1)),
'Data' = SUBSTRING(@String,stpos,COALESCE(NULLIF(endpos,0),LEN(@String)+1)-stpos)
FROM Split
)
创建如下所示的函数,返回逗号分隔名称
CREATE FUNCTION [dbo].[GetCommaSeperatedCategory]
(
@Codes VARCHAR(50)
)
RETURNS VARCHAR(5000)
AS
BEGIN
-- Declare the return variable here
DECLARE @Categories VARCHAR(5000)
SELECT @Categories= STUFF
(
(SELECT ',' + convert(varchar(10), Name, 120)
FROM Category
WHERE Code IN (SELECT Id FROM [dbo].[fnSplit] (@Codes,',') )
ORDER BY Code
FOR XML PATH (''))
, 1, 1, '')
RETURN @Categories
END
和最后:
SELECT
Tenant,
Code,
(SELECT [dbo].[GetCommaSeperatedCategory] (Code)) AS Name
FROM TblTenant