22,210
社区成员
发帖
与我相关
我的任务
分享
SELECT t1.*, t2.*, t3.Color, t3.S1, t3.S3, t3.S4 FROM 表1 t1
LEFT JOIN 表2 t2 ON t1.SaleId = t2.SaleID
LEFT JOIN (
SELECT SaleIDNum, Color, S1, NULL as S3, NULL as S4 FROM 表3 WHERE S1 <> 0
UNION ALL
SELECT SaleIDNum, Color, NULL, S3, NULL FROM 表3 WHERE S3 <> 0
UNION ALL
SELECT SaleIDNum, Color, NULL, NULL, S4 FROM 表3 WHERE S4 <> 0
) t3 ON t3.SaleIDNum = t2.SaleIDNum
SELECT ',['+Name+']' FROM SysColumns WHERE id = Object_Id( '表名' ) AND NAME LIKE 'S%' FOR XML PATH('')
对列名进行动态获取(如果以后会有S13 S14 或者 对列进行调整的情况存在)
declare @dynameicField nvarchar(100) ='', --动态字段名
@sql nvarchar(max) =''
;with cte as (
--尺码表
select distinct type from #c a
unpivot (qty for type in([S1],[S2],[S3],[S4],[S5],[S6],[S7],[S8],[S9],[S10],[S11],[S12]))b
)
-- select * from cte
//动态列名拼接
select @dynameicField = stuff(( select (',['+type+ ']') from cte order by cast(replace(type,'s','') as int) for xml path('')),1,1,'')
set @sql = N'with cte as ('
set @sql +='select *'
set @sql +=',qty as quantity'
set @sql +=',row_number() over(partition by saleidnum,color order by getdate()) as rn'
set @sql +=' from #c as a'
set @sql +=' unpivot (qty for type in([S1],[S2],[S3],[S4],[S5],[S6],[S7],[S8],[S9],[S10],[S11],[S12])) b )'
set @sql +='select saleid,codeid,billdate,goodsno,quantity,amount,color'
set @sql +=','+@dynameicField
set @sql += ' from ('
set @sql +='select a.saleid'
set @sql +=',a.codeid'
set @sql +=',a.billdate'
set @sql +=',b.goodsno'
set @sql +=',b.price as amount'
set @sql +=',c.*'
set @sql +=' from #a a'
set @sql +=' join #b b on a.saleid = b.saleid'
set @sql +=' join cte c on b.saleidnum = c.saleidnum'
set @sql +=')a'
set @sql +=' pivot (max(qty) for type in ('+@dynameicField+')) d'
exec sp_executesql @sql
最后生成的动态语句和输出结果:
DECLARE @SQL VARCHAR(MAX)
WITH CTE
AS
(SELECT DISTINCT TYPE
FROM #C AS A
UNPIVOT (QTY FOR TYPE IN ([S1],[S2],[S3],[S4],[S5],[S6],[S7],[S8],[S9],[S10],[S11],[S12])) B)
SELECT @SQL=STUFF((SELECT (',['+TYPE+']')
FROM CTE
ORDER BY CAST(REPLACE(TYPE,'S','') AS INT)
FOR XML PATH('')),1,1,'')
SET @SQL='WITH CTE
AS
(SELECT *,QTY AS QUANTITY,ROW_NUMBER() OVER (PARTITION BY SALEIDNUM,COLOR ORDER BY GETDATE()) AS RN
FROM #C AS A
UNPIVOT (QTY FOR TYPE IN ([S1],[S2],[S3],[S4],[S5],[S6],[S7],[S8],[S9],[S10],[S11],[S12])) B)
SELECT *
FROM
(SELECT A.SALEID,A.CODEID,A.DATE,B.GOODSNO,B.PRICE,C.*
FROM #A AS A
JOIN #B AS B ON A.SALEID=B.SALEID
JOIN CTE AS C ON B.SALEIDNUM=C.SALEIDNUM) AS A
PIVOT (MAX(QTY) FOR TYPE IN ('+@SQL+')) D'
EXEC(@SQL)
/*
if object_id('tempdb..#A') is not null
drop table #A
go
create table #A(
SaleId varchar(10),
CodeId int,
BillDate date
)
insert into #A
select 'CMK0101201',172101,'2020-04-05'
-- select * from #a
if object_id('tempdb..#B') is not null
drop table #B
go
create table #B(
SaleIDNum varchar(15),
SaleId varchar(10),
GoodsNo bigint,
Quantity int,
Price decimal(10,2)
)
insert into #B
select 'CMK01012010001','CMK0101201',621536472210,2,325 union all
select 'CMK01012010002','CMK0101201',821236475211,1,75
-- select * from #B
if object_id('tempdb..#C') is not null
drop table #C
go
create table #C(
id int identity(1,1) not null,
SaleIDNum varchar(15),
Color int,
S1 int,
S2 int,
S3 int,
S4 int,
S5 int,
S6 int,
S7 int,
S8 int,
S9 int,
S10 int,
S11 int,
S12 int
)
insert into #C(SaleIDNum,Color,S1,S3,S4)
select 'CMK01012010001',411,1,null,null union all
select 'CMK01012010001',411,null,1,null union all
select 'CMK01012010001',411,null,null,1
-- select * from #C as c
*/
--查询体
declare @minId int,
@maxId int,
@SaleIDNum varchar(15),
@Color int,
@S1 int,
@S2 int,
@S3 int,
@S4 int,
@S5 int,
@S6 int,
@S7 int,
@S8 int,
@S9 int,
@S10 int,
@S11 int,
@S12 int
/*
--变量体
declare @variable table(
SaleIDNum varchar(15),
Color int,
S1 int,
S2 int,
S3 int,
S4 int,
S5 int,
S6 int,
S7 int,
S8 int,
S9 int,
S10 int,
S11 int,
S12 int
)
*/
select @minId = min(id),@maxId = max(id) from #C
-- select @minId,@maxId
declare @sql nvarchar(max) =''
set @sql =N'select a.SaleId'
set @sql += ',a.CodeId'
set @sql += ',a.BillDate'
set @sql += ',b.GoodsNo'
set @sql += ',b.Quantity'
set @sql += ',b.Price * b.Quantity as Amount'
set @sql += ',c.Color'
set @sql += ',0 as ''内长'''
-- select @sql
--遍历执行
while(@minId is not null and @minId <=@maxId)
begin
select @SaleIDNum =@SaleIDNum
,@Color =Color
,@S1 =S1
,@S2 =S2
,@S3 =S3
,@S4 =S4
,@S5 =S5
,@S6 =S7
,@S7 =S7
,@S8 =S8
,@S9 =S9
,@S10 =S10
,@S11 =S11
,@S12 =S12
from #C where id = @minId
-- select @SaleIDNum,@Color,@S1
if isnull(datalength(@S1),0) >0
set @sql += ',c.S1'
if isnull(datalength(@S2),0) >0
set @sql += ',c.S2'
if isnull(datalength(@S3),0) >0
set @sql += ',c.S3'
if isnull(datalength(@S4),0) >0
set @sql += ',c.S4'
if isnull(datalength(@S5),0) >0
set @sql += ',c.S5'
if isnull(datalength(@S6),0) >0
set @sql += ',c.S6'
if isnull(datalength(@S7),0) >0
set @sql += ',c.S7'
if isnull(datalength(@S8),0) >0
set @sql += ',c.S8'
if isnull(datalength(@S9),0) >0
set @sql += ',c.S9'
if isnull(datalength(@S10),0) >0
set @sql += ',c.S10'
if isnull(datalength(@S11),0) >0
set @sql += ',c.S11'
if isnull(datalength(@S12),0) >0
set @sql += ',c.S12'
set @minId = @minId +1
end
set @sql += ' from #A a'
set @sql += ' inner join #B b on a.SaleId = b.SaleID'
set @sql += ' inner join #C c on b.SaleIDNum = c.SaleIDNum'
-- select @sql
exec sp_executesql @sql
go
输出结果:
/*
if object_id('tempdb..#A') is not null
drop table #A
go
create table #A(
SaleId varchar(10),
CodeId int,
BillDate date
)
insert into #A
select 'CMK0101201',172101,'2020-04-05'
-- select * from #a
if object_id('tempdb..#B') is not null
drop table #B
go
create table #B(
SaleIDNum varchar(15),
SaleId varchar(10),
GoodsNo bigint,
Quantity int,
Price decimal(10,2)
)
insert into #B
select 'CMK01012010001','CMK0101201',621536472210,2,325 union all
select 'CMK01012010002','CMK0101201',821236475211,1,75
-- select * from #B
if object_id('tempdb..#C') is not null
drop table #C
go
create table #C(
id int identity(1,1) not null,
SaleIDNum varchar(15),
Color int,
S1 int,
S2 int,
S3 int,
S4 int,
S5 int,
S6 int,
S7 int,
S8 int,
S9 int,
S10 int,
S11 int,
S12 int
)
insert into #C(SaleIDNum,Color,S1,S3,S4)
select 'CMK01012010001',411,1,1,null union all
select 'CMK01012010002',366,null,null,1
-- select * from #C as c
*/
--查询体
declare @minId int,
@maxId int,
@SaleIDNum varchar(15),
@Color int,
@S1 int,
@S2 int,
@S3 int,
@S4 int,
@S5 int,
@S6 int,
@S7 int,
@S8 int,
@S9 int,
@S10 int,
@S11 int,
@S12 int
select @minId = min(id),@maxId = max(id) from #C
-- select @minId,@maxId
declare @dynameicField varchar(100) ='', --动态字段[列名]
@sql nvarchar(max) =''
--动态字段生成
while(@minId is not null and @minId <=@maxId)
begin
select @SaleIDNum =@SaleIDNum
,@Color =Color
,@S1 =S1
,@S2 =S2
,@S3 =S3
,@S4 =S4
,@S5 =S5
,@S6 =S7
,@S7 =S7
,@S8 =S8
,@S9 =S9
,@S10 =S10
,@S11 =S11
,@S12 =S12
from #C where id = @minId
-- select @SaleIDNum,@Color,@S1
if isnull(datalength(@S1),0) >0
set @dynameicField = ',S1'
if isnull(datalength(@S2),0) >0
set @dynameicField += ',S2'
if isnull(datalength(@S3),0) >0
set @dynameicField += ',S3'
if isnull(datalength(@S4),0) >0
set @dynameicField += ',S4'
if isnull(datalength(@S5),0) >0
set @dynameicField += ',S5'
if isnull(datalength(@S6),0) >0
set @dynameicField += ',S6'
if isnull(datalength(@S7),0) >0
set @dynameicField += ',S7'
if isnull(datalength(@S8),0) >0
set @dynameicField += ',S8'
if isnull(datalength(@S9),0) >0
set @dynameicField += ',S9'
if isnull(datalength(@S10),0) >0
set @dynameicField += ',S10'
if isnull(datalength(@S11),0) >0
set @dynameicField += ',S11'
if isnull(datalength(@S12),0) >0
set @dynameicField += ',S12'
set @minId = @minId +1
end
set @sql =N'select SaleId,CodeId,BillDate,GoodsNo,1 as Quantity,Amount,Color,[内长]'
set @sql += @dynameicField + ' from ('
set @sql += 'select a.SaleId'
set @sql += ',a.CodeId'
set @sql += ',a.BillDate'
set @sql += ',b.GoodsNo'
set @sql += ',b.Quantity'
set @sql += ',b.Price as Amount'
set @sql += ',c.Color'
set @sql += ',0 as ''内长'''
------------------------------------------------------------------------------------------------------------------------
-- select @dynameicField
set @sql += @dynameicField
set @sql += ' from #A a'
set @sql += ' inner join #B b on a.SaleId = b.SaleID'
set @sql += ' inner join #C c on b.SaleIDNum = c.SaleIDNum'
set @sql += ')a,master..spt_values s where a.Quantity>=s.number and s.type=''P'' and s.number >0'
-- select @sql
exec sp_executesql @sql
go
with ta as (
select 'CMK0101201' as SaleId,172101 as CodeId,CONVERT(date,'2020-4-5') as [date]
),tb as (
select 'CMK01012010001' as SaleIDNum,'CMK0101201' as SaleID,'621536472210' as GoodsNo,2 as Quantity,325 as Price
union all
select 'CMK01012010002','CMK0101201','821236475211',1,75
),tc as (
select 'CMK01012010001' as SaleIDNum,411 as Color,'1' as S1,'' as S2,'1' as S3,'' as S4
union all
select 'CMK01012010002',366,'','','','1'
)
select a.*,GoodsNo,Quantity,Price,Color,S1,S2,S3,S4
from (
select *
from (
select *
,ROW_NUMBER() over(order by getdate()) as rid -- 为了避免列转行,同样产品合并为一行,追加一个不重复列
from tc
unpivot(val for col in (S1,S2,S3,S4)) p
where val<>''
) a
pivot(
max(val) for col in (S1,S2,S3,S4)
) p
) c
left join tb b on c.SaleIDNum=b.SaleIDNum
left join ta a on b.SaleID=a.SaleId