如何为Table报告编写SQL程序

时间:2018-04-11 09:19:48

标签: sql sql-server

我有3张桌子:

enter image description here

我想编写过程,以便在更改表作业时,表格报告将相应更改

enter image description here

谢谢!

1 个答案:

答案 0 :(得分:0)

如果您使用SQL-Server 2016或更高版本

,则可以使用string_split
  

如果你没有SQL-Server 2016,那么谷歌搜索一个string_split函数 - 这个网站上有很多这样的函数,而是用它来代替string_split

这是一种使用动态SQL pivot

的方法

UPDATE2在值更改时使TableReport更改

这会检查TableReport是否存在,如果存在,则应该删除它。然后我在动态SQL中添加了一个SELECT INTO语句,重新创建了表。

DECLARE @Str NVARCHAR(MAX);
DECLARE @Str2 NVARCHAR(MAX);
SELECT @Str = STUFF(
                   (
                       SELECT DISTINCT
                              ','+QUOTENAME(Namejob)
                       FROM tablejob FOR XML PATH('')
                   ), 1, 1, '');
-- PRINT @Str
SET @str2 = N'select ROW_NUMBER() over(order by idemp) as ID,Name2 as Name, '+@Str+' into dbo.TableReport from (
select b.idemp,Names as Name2,Names,namejob from tablecustomer a cross apply dbo.[fn_split_string_using_multiple_delimiters](idjob,'','')
left join tableemp b on a.idemp =b.idemp
left join tablejob c on stringlist = c.idjob 
) z




PIVOT 
(count(names) for Namejob in ('+@Str+'
)
) as x';

IF OBJECT_ID('dbo.TableReport', 'U') IS NOT NULL 
  DROP TABLE dbo.TableReport; 
--PRINT @Str2;
EXEC (@Str2);

非SQL-Server2016版本的更新

  

首先,您必须创建一个分割字符串的函数

字符串拆分器功能

CREATE FUNCTION dbo.[fn_split_string_using_multiple_delimiters]
(
      @String    VARCHAR(MAX),  -- input string
      @delimiter VARCHAR(32)    -- delimiter list 
)
RETURNS @Table TABLE(rowid INT IDENTITY PRIMARY KEY,        
stringlist VARCHAR(MAX)
)
BEGIN

        DECLARE @Xml AS XML
        DECLARE @derived_string VARCHAR(MAX)

        ;WITH N1 (n) AS (SELECT 1 UNION ALL SELECT 1),
        N2 (n) AS (SELECT 1 FROM N1 AS X, N1 AS Y),
        N3 (n) AS (SELECT 1 FROM N2 AS X, N2 AS Y),
        N4 (n) AS (SELECT ROW_NUMBER() OVER(ORDER BY X.n)
        FROM N3 AS X, N3 AS Y)

        SELECT @derived_string=STUFF((SELECT '' + (Case When
                PATINDEX('%[' + @delimiter + ']%',SUBSTRING(@String,Nums.n,1)) >0
                Then ',' else LTRIM(RTRIM(SUBSTRING(@String,Nums.n,1))) end)
        FROM N4 Nums WHERE Nums.n<=LEN(@String)  FOR XML PATH('')),1,0,'')

        SET @Xml = cast(('<a>'+replace(@derived_string,
                ',','</a><a>')+'</a>') AS XML)

        INSERT INTO @Table SELECT A.value('.', 'VARCHAR(MAX)')
                as [Column] FROM @Xml.nodes('a') AS FN(a)

RETURN
END
GO
  

这个硬编码的SQL与2016年的string_split一样 - 它也是动态的。

带功能的带编码的SQL

select ROW_NUMBER() over(order by idemp) as ID,Name2 as Name, [A],[B],[C] from (
select b.idemp,Names as Name2,Names,namejob from tablecustomer a cross apply dbo.[fn_split_string_using_multiple_delimiters](idjob,',')
left join tableemp b on a.idemp =b.idemp
left join tablejob c on stringlist = c.idjob 
)x

PIVOT 
(count(names) for Namejob in ([A],[B],[C]
)
) as x

测试数据

   create  table dbo.tablejob  (idjob int, namejob varchar(50))
insert into tablejob
values
(1,'a'),
(2,'b'),
(3,'c')

create table dbo.tablecustomer (serialno int,idcustomer varchar(50),idemp varchar(50),idjob varchar(50))
insert into tablecustomer

values
(1,'0001','00001','1,3'),
(2,'0002','00002','1'),
(3,'0003','00001','2,3')

create table dbo.tableemp (idemp varchar(50),Names varchar(50))
insert into tableemp

values
('00001','Jon'),
('00002','Az')

动态SQL

DECLARE @Str NVARCHAR(MAX);
DECLARE @Str2 NVARCHAR(MAX);
SELECT @Str = STUFF(
                   (
                       SELECT DISTINCT
                              ','+QUOTENAME(Namejob)
                       FROM tablejob FOR XML PATH('')
                   ), 1, 1, '');
-- PRINT @Str
SET @str2 = N'select ROW_NUMBER() over(order by idemp) as ID,Name2 as Name, '+@Str+' from (
select b.idemp,Names as Name2,Names,namejob from tablecustomer a cross apply string_split(idjob,'','')
left join tableemp b on a.idemp =b.idemp
left join tablejob c on value = c.idjob 
) z




PIVOT 
(count(names) for Namejob in ('+@Str+'
)
) as x';

--PRINT @Str2;
EXEC (@Str2);

硬编码SQL

select ROW_NUMBER() over(order by idemp) as ID,Name2 as Name, [A],[B],[C] from (
select b.idemp,Names as Name2,Names,namejob from tablecustomer a cross apply string_split(idjob,',')
left join tableemp b on a.idemp =b.idemp
left join tablejob c on value = c.idjob 
)x




PIVOT 
(count(names) for Namejob in ([A],[B],[C]
)
) as x

<强>结果

enter image description here