sql每月身份

时间:2010-07-09 07:45:33

标签: sql sql-server

是否可以创建每月身份? 基本上我需要的是

create table
(
id identity primary key
regDate DateTime not null,
regDateNumber int not null
)

当我插入数据时,我需要将regDateNumber设置为regDate月份范围内的标识

像这样:

id   regDate    regDateNumber
1    1 jan 2008 1
2    3 jan 2008 2
3    7 jan 2008 3
4    1 feb 2008 1
5    1 feb 2008 2
6    1 aug 2008 1
7    1 aug 2008 2
8    1 sep 2008 1
9    1 sep 2008 2

4 个答案:

答案 0 :(得分:2)

你不能用身份来做,所以你可以在飞行中计算。 类似的东西:

select id, regDate, 
row_number() over(partition by year(regDate), month(regDate) as regDateNumber order by id) 
from t

答案 1 :(得分:2)

您只需在表格中添加一个计算列:

ALTER TABLE dbo.YourTable
  ADD regMonth AS MONTH(regDate) PERSISTED

并完成它。这将被计算,持久化(例如,不会在每次访问时重新计算,但仅在regDate更改时),包含日期的MONTH信息,甚至可以为速度编制索引。

更新:好的,所以现在我明白了 - 你的“每个月的身份”有点不清楚和误导。你想要的是按月顺序编号,对吧?

执行此操作的一种方法是不执行/不存储它,而是使用burnall的方法使用ROW_NUMBER()函数。

否则,您必须执行一个AFTER INSERT触发器来计算INSERT上的新值 - 但是这样会变得混乱而且b)当您''时会花费相当多的性能做了很多插入。

我的建议是使用burnall的功能并让其运行,例如每小时左右更新一次这些字段。 <{1}}时,不要试图在飞行中解决这个问题 - 你的表现会很糟糕。

答案 2 :(得分:1)

我相信您可以通过使用存储过程实现此目的:

CREATE PROCEDURE month_indentity
   @myInput  DateTime
AS
SELECT COUNT(*) + 1 FROM mytable
WHERE MONTH(regDate) = MONTH(@myInput)
    AND YEAR(regDate) = YEAR(@myInput)
GO

答案 3 :(得分:1)

create table #table (iid int identity (1, 1), dy int, mth varchar(3))

insert into #table (dy, mth)
select 1, 'jan' union all
select 2, 'jan' union all
select 20, 'jan' union all
select 10, 'jan' union all
select 1, 'feb' union all
select 3, 'feb' union all
select 28, 'feb' 

select T.dy, T.mth, 
  (select count(X.iid) from #table X where X.mth = T.mth and X.iid < T.iid) + 1 as month_rank
from #table T
order by T.mth, month_rank

我不会将该值存储为计算字段,因为它可能会随时间变化而违反规范化规则。