把一行分成多行,并给分出来的多行每行加一个9位全年不重复的值

流水号20191104059 2019-10-30 09:10:18
原表
列1 列2 列3 列4 列5
A 35 30 2 N
B 51 17 3 N
C 14 14 1 M

需要的效果

列1 列2 列3 列4 列5 列6 列7 列8
A 35 30 2 N 30 null 191030001
A 35 30 2 N 5 null 191030002
B 51 17 3 N 17 null 191030003
B 51 17 3 N 17 null 191030004
B 51 17 3 N 17 null 191030005
C 14 14 1 M 14 191030005 191030006

列4列2列3 的倍数向上取整,列4 为几 列1 的这个物料就被分配成几行

列6 的总和等于 列2 的值

列5 为 'N' 的时候 列7 为NULL ,当 列5 为'M'的时候,列7列8都要有号码,列7列8的值为9位全年不重复
...全文
525 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
谁能解决?
  • 打赏
  • 举报
回复
沉了嘛?为什么没人回复
  • 打赏
  • 举报
回复
引用 30 楼 Dear SQL 的回复:
[quote=引用 29 楼 qq_24914059 的回复:] [quote=引用 27 楼 Dear SQL 的回复:] [quote=引用 26 楼 qq_24914059 的回复:] [quote=引用 25 楼 Dear SQL 的回复:] [quote=引用 24 楼 qq_24914059 的回复:] [quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
[/quote] 运行之后显示全是空值[/quote] 把运行的SQL发出来[/quote] 运行存储过程结果是NULL,然后我查看代码中的两个表,也都是空表[/quote] 在上面第一点,要在表中SysSequence配置记录
insert into [dbo].[SysSequence]([AccId],[SequenceName],[ChineseName],[Prefix],[DateLength],[Width],[CurrentValue],[CreateDate],[Creator],[Updater],[UpdateDate]
 ,[IsDelete],[CreatorCode],[UpdaterCode],[OperDept],[RoCode])
select [AccId]=1,[SequenceName]='test',[ChineseName]='测试',[Prefix]='T',[DateLength]=6,[Width]=4,[CurrentValue]='',[CreateDate]=GETDATE(),[Creator]='',[Updater]='',[UpdateDate]=GETDATE()
 ,[IsDelete]=0,[CreatorCode]='',[UpdaterCode]='',[OperDept]='',[RoCode]=''

declare @rtn varchar(50)

EXEC up_Sys_GetSequenceNO_Multi 1,'test',1,@rtn out,null

select @rtn
[/quote] 我的这个原表是发货需求,而需要的效果是运单,列1是商品名,列2是本次数量,列3是商品的最小包装数, 列4是我计算的把本次发货的数量拆分成几行运单显示,商品有两种包装,一种是M,需要两个识别码, 一种为N的包装只要一个识别码,最种这个运单还有一个运单号码,运单号是8位,识别码是9位, 第一,作为运单,就会有重复打印的需求,所以我需要把生成的运行进行保存, 第二,每天可能有多次发货,随意用日期做识别码和运单号码,都要每天重置一次,从1开始, 这样可以保证全年不重复,同时方便以后查询。这些是我的需求
Dear SQL(燊) 2019-11-21
  • 打赏
  • 举报
回复
引用 29 楼 qq_24914059 的回复:
[quote=引用 27 楼 Dear SQL 的回复:] [quote=引用 26 楼 qq_24914059 的回复:] [quote=引用 25 楼 Dear SQL 的回复:] [quote=引用 24 楼 qq_24914059 的回复:] [quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
[/quote] 运行之后显示全是空值[/quote] 把运行的SQL发出来[/quote] 运行存储过程结果是NULL,然后我查看代码中的两个表,也都是空表[/quote] 在上面第一点,要在表中SysSequence配置记录
insert into [dbo].[SysSequence]([AccId],[SequenceName],[ChineseName],[Prefix],[DateLength],[Width],[CurrentValue],[CreateDate],[Creator],[Updater],[UpdateDate]
 ,[IsDelete],[CreatorCode],[UpdaterCode],[OperDept],[RoCode])
select [AccId]=1,[SequenceName]='test',[ChineseName]='测试',[Prefix]='T',[DateLength]=6,[Width]=4,[CurrentValue]='',[CreateDate]=GETDATE(),[Creator]='',[Updater]='',[UpdateDate]=GETDATE()
 ,[IsDelete]=0,[CreatorCode]='',[UpdaterCode]='',[OperDept]='',[RoCode]=''

declare @rtn varchar(50)

EXEC up_Sys_GetSequenceNO_Multi 1,'test',1,@rtn out,null

select @rtn
  • 打赏
  • 举报
回复
引用 27 楼 Dear SQL 的回复:
[quote=引用 26 楼 qq_24914059 的回复:] [quote=引用 25 楼 Dear SQL 的回复:] [quote=引用 24 楼 qq_24914059 的回复:] [quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
[/quote] 运行之后显示全是空值[/quote] 把运行的SQL发出来[/quote] 运行存储过程结果是NULL,然后我查看代码中的两个表,也都是空表
  • 打赏
  • 举报
回复
我的这个原表是发货需求,而需要的效果是运单,列1是商品名,列2是本次数量,列3是商品的最小包装数, 列4是我计算的把本次发货的数量拆分成几行运单显示,商品有两种包装,一种是M,需要两个识别码, 一种为N的包装只要一个识别码,最种这个运单还有一个运单号码,运单号是8位,识别码是9位, 第一,作为运单,就会有重复打印的需求,所以我需要把生成的运行进行保存, 第二,每天可能有多次发货,随意用日期做识别码和运单号码,都要每天重置一次,从1开始, 这样可以保证全年不重复,同时方便以后查询。
Dear SQL(燊) 2019-11-19
  • 打赏
  • 举报
回复
引用 26 楼 qq_24914059 的回复:
[quote=引用 25 楼 Dear SQL 的回复:] [quote=引用 24 楼 qq_24914059 的回复:] [quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
[/quote] 运行之后显示全是空值[/quote] 把运行的SQL发出来
  • 打赏
  • 举报
回复
引用 25 楼 Dear SQL 的回复:
[quote=引用 24 楼 qq_24914059 的回复:] [quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
[/quote] 运行之后显示全是空值
  • 打赏
  • 举报
回复
引用 21 楼 Dear SQL 的回复:

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值
zjcxc 2019-11-15
  • 打赏
  • 举报
回复
SELECT CONVERT(varchar(10),GETDATE(),112)+RIGHT(1000000000+NEXT VALUE FOR SEQ_ID,9)
zjcxc 2019-11-15
  • 打赏
  • 举报
回复
引用 13 楼 qq_24914059 的回复:
[quote=引用 12 楼 zjcxc--个人微信公共号同名 的回复:]
不重复值可以直接用 secuence 嘛,不管你在任何地方以任何使用,调用一次都会+1,这样始终就不会重复了
CREATE SEQUENCE SEQ_ID AS bigint START WITH 1;
GO

SELECT NEXT VALUE FOR SEQ_ID;

DECLARE @id int = NEXT VALUE FOR SEQ_ID;
SELECT @id, NEXT VALUE FOR SEQ_ID;

SELECT RIGHT(1000000000+NEXT VALUE FOR SEQ_ID,9)
FROM( SELECT TOP(10) * FROM sys.tables )DATA




可以每天更新,回到初始值1嘛?
[/quote]

可以建个 job 在每天 0 点执行
LTER SEQUENCE [schema_name. ] sequence_name
[ RESTART [ WITH <constant> ] ]
但并不建议,毕竟你很难非常精确的卡到点,所以如果是要按天,你可以考虑不管序号,但把日期附加到序号前面
Dear SQL(燊) 2019-11-15
  • 打赏
  • 举报
回复
引用 24 楼 qq_24914059 的回复:
[quote=引用 21 楼 Dear SQL 的回复:]

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
当天第一次触发这样是没问题,如果当天的第二次,或者第N次,有个选择,第一是需要把列7,和列8的流水号在继续增加,第二种可能是重新显示第一次的值[/quote] 这个要建个配置参数表 1.在表中SysSequence配置记录 2.调用SP:up_Sys_GetSequenceNO_Multi 传相应参数 3.表SysSequenceSub 记录每天最大流水号(不需要手动维护,自动产生)

CREATE TABLE [dbo].[SysSequenceSub](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[DateStr] [varchar](50) NOT NULL,
	[CurrentValue] [bigint] NOT NULL,
	[Creator] [nvarchar](50) NULL,
	[CreateDate] [datetime] NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequenceSub] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC,
	[DateStr] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/****** Object:  Table [dbo].[SysSequence]    Script Date: 2019-11-15 15:22:07 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[SysSequence](
	[AccId] [smallint] NOT NULL,
	[SequenceName] [varchar](50) NOT NULL,
	[ChineseName] [varchar](50) NULL,
	[Prefix] [varchar](5) NOT NULL,
	[DateLength] [int] NOT NULL,
	[Width] [int] NOT NULL,
	[CurrentValue] [varchar](50) NOT NULL,
	[CreateDate] [datetime] NULL,
	[Creator] [nvarchar](50) NULL,
	[Updater] [nvarchar](50) NULL,
	[UpdateDate] [datetime] NULL,
	[IsDelete] [tinyint] NOT NULL,
	[CreatorCode] [nvarchar](50) NULL,
	[UpdaterCode] [nvarchar](50) NULL,
	[OperDept] [nvarchar](50) NULL,
	[RoCode] [varchar](50) NULL,
 CONSTRAINT [PK_SysSequence] PRIMARY KEY CLUSTERED 
(
	[AccId] ASC,
	[SequenceName] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE PROCEDURE [dbo].[up_Sys_GetSequenceNO_Multi]
    @AccId smallint,
	@SequenceName varchar(50),
	@count int,
	@rtn varchar(50) output,
    @Width int output,
	@Prefix varchar(50)=null,
	@date datetime=null
AS
set nocount on;
--Declare @Prefix varchar(5)
Declare @DateLength int
--Declare @Width int
Declare @NowDate varchar(8),@CheckStr varchar(1),@CurrentValue bigint
declare @Mark varchar(50)='' --标记是否外部前缀
if @Prefix<>'' set @Mark=@Prefix
	
select @Prefix = case when isnull(@Prefix,'')<>'' then @Prefix else Prefix end,@DateLength = DateLength,@Width = Width,@CheckStr='Y'
from dbo.SysSequence
where SequenceName = @SequenceName and AccId=@AccId

set @rtn=''
if isnull(@CheckStr,'')='' return;
if @date is null set @date=getdate()

Set @NowDate = left(Convert(char(8),@date,12),@DateLength)

merge dbo.SysSequenceSub tg
using (select AccId=@AccId,SequenceName=@SequenceName,DateStr=@Mark+@NowDate,CurrentValue=@count,CreateDate=getdate(),IsDelete=0) su
on tg.AccId=su.AccId and tg.SequenceName=su.SequenceName and  tg.DateStr=su.DateStr
when matched then
	update set tg.CurrentValue=tg.CurrentValue+su.CurrentValue
		,@CurrentValue=tg.CurrentValue+su.CurrentValue
when not matched then
	insert (AccId,SequenceName,DateStr,CurrentValue,CreateDate,IsDelete)
	values(su.AccId,su.SequenceName,su.DateStr,su.CurrentValue,su.CreateDate,su.IsDelete)
;
set @rtn= @Prefix+@NowDate+ right(Replicate('0', @Width)+cast(isnull(@CurrentValue,@count) as varchar(20)), @Width)
ダ雨夹雪リ 2019-11-13
  • 打赏
  • 举报
回复
拆分的纪录数,这个啊,你换掉,你拆分出来 有多少 记录,这里就填多少

EXEC sp_getvalue '2019',10
  • 打赏
  • 举报
回复
引用 18 楼 雨夹雪 的回复:


--创建一个计数器的表,按年流水,最小值100000000
CREATE TABLE A
(
 y VARCHAR(4),
 v BIGINT
)
 GO
 
--创建存储过程按年取数 
create PROCEDURE sp_getvalue(@y VARCHAR(4),@cnt int)
as
BEGIN
	IF @cnt<=0
		return
	if not exists(select 1  from A where y=@y)
	begin
		insert into A values(@y,100000000)
	end
	
	DECLARE @rst TABLE(V BIGINT)
	UPDATE A SET v=v+@cnt OUTPUT Deleted.v INTO @rst WHERE y=@y

	;
	with ct
	as
	(
		select 1 as id,V+1 As V  from @rst
		union all
		select ID+1,V+1 from ct where id<@cnt
	) 
	SELECT * from ct 
end 
 
--你的拆分
 
--临时使用 
create table #T
(
	id int,
	val bigint
)

insert into #T(id,val)
EXEC sp_getvalue '2019',拆分的纪录数


--按纪录号关联更新
 
drop table #T
执行的时候提示,从数据型nvarchar 转换int时出错
ダ雨夹雪リ 2019-11-13
  • 打赏
  • 举报
回复


--创建一个计数器的表,按年流水,最小值100000000
CREATE TABLE A
(
y VARCHAR(4),
v BIGINT
)
GO

--创建存储过程按年取数
create PROCEDURE sp_getvalue(@y VARCHAR(4),@cnt int)
as
BEGIN
IF @cnt<=0
return
if not exists(select 1 from A where y=@y)
begin
insert into A values(@y,100000000)
end

DECLARE @rst TABLE(V BIGINT)
UPDATE A SET v=v+@cnt OUTPUT Deleted.v INTO @rst WHERE y=@y

;
with ct
as
(
select 1 as id,V+1 As V from @rst
union all
select ID+1,V+1 from ct where id<@cnt
)
SELECT * from ct
end

--你的拆分

--临时使用
create table #T
(
id int,
val bigint
)

insert into #T(id,val)
EXEC sp_getvalue '2019',拆分的纪录数


--按纪录号关联更新

drop table #T
  • 打赏
  • 举报
回复
引用 16 楼 advance_coder 的回复:
[quote=引用 15 楼 qq_24914059的回复:][quote=引用 14 楼 advance_coder 的回复:] 一个整形正好四个字节,无符号整形的最大值2的32次方(4,294,967,296),一秒等于1千微秒。 那么一微秒产生一个计数,一个无符号整形可以使用的时间为t t=(4,294,967,296)/(365*24*60*60*1000) t=49.71年,取整t=49年 要求9年不重复 x=t/9=5.44,取整为5 则9年后最大计数为 n=(4,294,967,296)/(5)=858,993,459.2 n取整858,993,459,最大值正好九位数,满足要求。 验证y=(858,993,459)/(9*24*60*60*1000) y=1.105>1,绝对满足要求。 所以采用四字节无符号整形计数可以满足要求。 c语言里面有个GetTickCount函数,可以考虑使用他来做计数器。
不会用,太难了 [/quote] 仔细看了一下,安卓计算器有bug,4个字节不够用,用八个字节(uint64_t)是绝对可以的。[/quote] 能按我的描述给我一段可以执行的代码嘛?
Dear SQL(燊) 2019-11-13
  • 打赏
  • 举报
回复

if object_id('tempdb..#list') is not null drop table #list
 
select 列1='A',列2=35,列3=30,列4=2,列5='N' into #list union all
select 列1='B',列2=51,列3=17,列4=3,列5='N' union all
select 列1='C',列2=14,列3=14,列4=1,列5='M' 

;
with list as(
	select *,mark=cast(列2/列3 as int)+iif(列2%列3>0,1,0),mark2=列2%列3
	from #list
)
select 列1,a.列2,a.列3,a.列4,a.列5
	,列6=case when b.number+1<a.mark then 列3
			  when b.number+1=a.mark and mark2>0 then mark2
			  else 列3
		 end
	,[列7]=case when 列5='N' then null
				else '19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)-1) as varchar(4)),4)
		   end
	,[列8]='19103'+right('0000'+cast( (ROW_NUMBER()over(order by 列1,a.mark desc)) as varchar(4)),4)
from list a
inner join master.dbo.spt_values b on b.number+1<=a.mark
where b.type='P'
ORDER BY 列1,a.mark desc

/*
列1   列2          列3          列4          列5   列6          列7            列8
---- ----------- ----------- ----------- ---- ----------- ------------- -------------
A    35          30          2           N    30          NULL          191030001
A    35          30          2           N    5           NULL          191030002
B    51          17          3           N    17          NULL          191030003
B    51          17          3           N    17          NULL          191030004
B    51          17          3           N    17          NULL          191030005
C    14          14          1           M    14          191030005     191030006
*/
advance_coder 2019-11-12
  • 打赏
  • 举报
回复
引用 15 楼 qq_24914059的回复:
[quote=引用 14 楼 advance_coder 的回复:] 一个整形正好四个字节,无符号整形的最大值2的32次方(4,294,967,296),一秒等于1千微秒。 那么一微秒产生一个计数,一个无符号整形可以使用的时间为t t=(4,294,967,296)/(365*24*60*60*1000) t=49.71年,取整t=49年 要求9年不重复 x=t/9=5.44,取整为5 则9年后最大计数为 n=(4,294,967,296)/(5)=858,993,459.2 n取整858,993,459,最大值正好九位数,满足要求。 验证y=(858,993,459)/(9*24*60*60*1000) y=1.105>1,绝对满足要求。 所以采用四字节无符号整形计数可以满足要求。 c语言里面有个GetTickCount函数,可以考虑使用他来做计数器。
不会用,太难了 [/quote] 😓仔细看了一下,安卓计算器有bug,4个字节不够用,用八个字节(uint64_t)是绝对可以的。
  • 打赏
  • 举报
回复
引用 14 楼 advance_coder 的回复:
一个整形正好四个字节,无符号整形的最大值2的32次方(4,294,967,296),一秒等于1千微秒。 那么一微秒产生一个计数,一个无符号整形可以使用的时间为t t=(4,294,967,296)/(365*24*60*60*1000) t=49.71年,取整t=49年 要求9年不重复 x=t/9=5.44,取整为5 则9年后最大计数为 n=(4,294,967,296)/(5)=858,993,459.2 n取整858,993,459,最大值正好九位数,满足要求。 验证y=(858,993,459)/(9*24*60*60*1000) y=1.105>1,绝对满足要求。 所以采用四字节无符号整形计数可以满足要求。 c语言里面有个GetTickCount函数,可以考虑使用他来做计数器。
不会用,太难了
advance_coder 2019-11-08
  • 打赏
  • 举报
回复
一个整形正好四个字节,无符号整形的最大值2的32次方(4,294,967,296),一秒等于1千微秒。 那么一微秒产生一个计数,一个无符号整形可以使用的时间为t t=(4,294,967,296)/(365*24*60*60*1000) t=49.71年,取整t=49年 要求9年不重复 x=t/9=5.44,取整为5 则9年后最大计数为 n=(4,294,967,296)/(5)=858,993,459.2 n取整858,993,459,最大值正好九位数,满足要求。 验证y=(858,993,459)/(9*24*60*60*1000) y=1.105>1,绝对满足要求。 所以采用四字节无符号整形计数可以满足要求。 c语言里面有个GetTickCount函数,可以考虑使用他来做计数器。
加载更多回复(13)

27,579

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 应用实例
社区管理员
  • 应用实例社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧