我的列包含字符:
TABLE1
======
id | divs
----------
11 | A
12 | AB
13 | C
14 | E
15 | BDE
16 | F
每个char代表不同的分区,第二个表是:
TABLE2
======
id | div | TABLE1_id | report
------------------------------
21 | A | 11 | "Lorem ipsum 1"
22 | B | 12 | "Lorem ipsum 2"
23 | C | 13 | "Lorem ipsum 3"
24 | A | 12 | "Lorem ipsum 4"
25 | B | 15 | "Lorem ipsum 5"
26 | F | 16 | "Lorem ipsum 6"
最终报告是:
Reports
=======
TABLE1_id | TABLE2_id | div | report
------------------------------------
11 | 21 | A | "Lorem ipsum 1"
12 | 24 | A | "Lorem ipsum 4"
12 | 22 | B | "Lorem ipsum 2"
13 | 23 | C | "Lorem ipsum 3"
14 | NULL | E | NULL
15 | 25 | B | "Lorem ipsum 5"
15 | NULL | D | NULL
15 | NULL | E | NULL
16 | 26 | F | "Lorem ipsum 6"
字数限制为5:" ABCDE",
我尝试了很多SQL查询,但显然我遗漏了一些东西,并且不知道一些重要的命令...
如何在MSSQL中生成该报告?
答案 0 :(得分:3)
通常你需要一个计数表。由于您的字符串有限,您可以使用自己生成的数字
declare @t1 table (
id int
, divs varchar(5)
)
insert into @t1
values
(11, 'A')
,(12, 'AB')
,(13, 'C')
,(14, 'E')
,(15, 'BDE')
,(16, 'F')
declare @t2 table (
id int
, div varchar(5)
, TABLE1_id int
, report varchar(200)
)
insert into @t2
values
(21, 'A', 11, '"Lorem ipsum 1"')
,(22, 'B', 12, '"Lorem ipsum 2"')
,(23, 'C', 13, '"Lorem ipsum 3"')
,(24, 'A', 12, '"Lorem ipsum 4"')
,(25, 'B', 15, '"Lorem ipsum 5"')
,(26, 'F', 16, '"Lorem ipsum 6"')
select
t.id, z.id, substring(t.divs, q.n, 1), z.report
from
@t1 t
join (values (1), (2), (3), (4), (5)) q(n) on len(t.divs) >= q.n
left join @t2 z on substring(t.divs, q.n, 1) = z.div and t.id = z.TABLE1_id
答案 1 :(得分:2)
您可以使用2016年提供的string_split功能
这样做declare @myt table (id int, divs nvarchar(50)
)
insert into @myt
values
(11 ,'A' ),
(12 ,'AB' ),
(13 ,'C' ),
(14 ,'E' ),
(15 ,'BDE'),
(16 ,'F' )
declare @myt2 table (id int,div nvarchar(50),table1_id int, report nvarchar(50))
insert into @myt2
values
(21 ,'A',11,'"Lorem ipsum 1"'),
(22 ,'B',12,'"Lorem ipsum 2"'),
(23 ,'C',13,'"Lorem ipsum 3"'),
(24 ,'A',12,'"Lorem ipsum 4"'),
(25 ,'B',15,'"Lorem ipsum 5"'),
(26 ,'F',16,'"Lorem ipsum 6"')
select x.id,b.id as Table1_id,[value],report from (
select *,substring(divs,1,1)+','+substring(divs,2,1)+','+substring(divs,3,1)+','+substring(divs,4,1)+','+substring(divs,5,1) as divs2 from @myt
) x
cross apply string_split(divs2,',')
left join @myt2 b on x.id = b.table1_id and b.div = [value]
where value!= ''
答案 2 :(得分:2)
由于OP尚未针对他们尝试过的请求发布回复,我故意将此不完整。向我们展示你以前尝试过的东西是一种很好的做法;我们不是为你做的工作。
OP,您需要向此正确添加SELECT
子句,将相关列添加到CROSS APPLY
并完成CREATE TABLE #Table1 (id tinyint,
divs varchar(5));
CREATE TABLE #Table2 (id tinyint,
div char(1),
Table1_id tinyint,
report varchar(50));
INSERT INTO #Table1
VALUES (11,'A'),
(12,'AB'),
(13,'C'),
(14,'E'),
(15,'BDE'),
(16,'F');
INSERT INTO #Table2
VALUES (21,'A',11,'"Lorem ipsum 1"'),
(22,'B',12,'"Lorem ipsum 2"'),
(23,'C',13,'"Lorem ipsum 3"'),
(24,'A',12,'"Lorem ipsum 4"'),
(25,'B',15,'"Lorem ipsum 5"'),
(26,'F',16,'"Lorem ipsum 6"');
GO
SELECT *
FROM #Table1 T1
CROSS APPLY (VALUES(SUBSTRING(T1.divs,1,1)),(SUBSTRING(T1.divs,2,1))) D(div)
LEFT JOIN #Table2 T2 ON T1.id = T2.Table1_id
AND D.div = T2.div;
GO
DROP TABLE #Table1;
DROP TABLE #Table2;
(它只能处理目前前2个div)。如果您不明白,请询问:
min
答案 3 :(得分:1)
其他选项是使用 admin-name
cte方法,该方法不仅限于5个字符
recursive
结果:
;with cte as
(
select id, divs, len(divs) pos, 1 start
from table1
), cte1 as
(
select id, divs, pos, start, '' splitdivs from cte
union all
select id, divs, pos, start+1, substring(divs, start+1, 1) splitdivs
from cte1
where pos > start
)
select c.id TABLE1_id, t2.id TABLE2_id,
(case when splitdivs = '' then substring(divs, 1,1) else splitdivs end) div,
t2.report
from cte1 c
left join table2 t2 on t2.TABLE1_id = c.id and
t2.div = (case when splitdivs = '' then substring(divs, 1,1) else splitdivs end)
order by 1
答案 4 :(得分:1)
另一种解决方案:
免责声明我没有看到Uzi已经发布了类似的解决方案
DECLARE @Tbl TABLE (Id int , Divs nvarchar(5))
INSERT INTO @Tbl (Id, Divs)
SELECT 11 , 'A'
UNION ALL
SELECT 12 , 'AB'
UNION ALL
SELECT 13 , 'C'
UNION ALL
SELECT 14 , 'E'
UNION ALL
SELECT 15 , 'BDE'
UNION ALL
SELECT 16 , 'F'
DECLARE @Tbl2 TABLE (Id INT , Div NVARCHAR(1), Table1_Id INT , Report nvarchar(20))
INSERT INTO @Tbl2 (Id, Div , Table1_Id , Report)
SELECT 21 , 'A' , 11 , '"Lorem ipsum 1"'
UNION ALL
SELECT 22 , 'B' , 12 , '"Lorem ipsum 2"'
UNION ALL
SELECT 23 , 'C' , 13 , '"Lorem ipsum 3"'
UNION ALL
SELECT 24 , 'A' , 12 , '"Lorem ipsum 4"'
UNION ALL
SELECT 25 , 'B' , 15 , '"Lorem ipsum 5"'
UNION ALL
SELECT 26 , 'F' , 16 , '"Lorem ipsum 6"'
;WITH nums (n)
AS
(
SELECT ROW_NUMBER () OVER (ORDER BY (SELECT NULL))
FROM (VALUES (0),(0),(0),(0),(0)) a(n)
)
, Tbl1 as
(
SELECT Id , SUBSTRING(Divs,n,1) Div
FROM @Tbl t
CROSS APPLY
(
VALUES (LEN(Divs))
) X(ChrLen)
CROSS JOIN nums n
WHERE n <= ChrLen
)
SELECT t1.Id Table1_Id , t2.Id Table2_Id ,t1.Div , t2.Report
FROM Tbl1 T1
LEFT JOIN @Tbl2 T2
ON T2 .Div = T1.Div
AND t1.Id = T2.Table1_Id