increment values on day basis on column

  • hi all,

    i want to generate id column values on the basis of every day.

    suppose table name like test and

    table have column id then value of id column are

    today is 28-aug-2012 then values are increased after each insert like this

    :-

    table name test

    column name ID

    and values are

    id

    2012082800001

    2012082800002

    ....

    ....

    2012082800002

    and next day it will be on new insert :-

    2012082900001

    2012082900002

    .......

    ........

    and next day it will be on new insert :-

    2012083000001

    2012083000002

    .......

    ........

  • Generating your own identity values isn't as straightforward as it might at first appear, the code for preventing concurrency issues is fairly complex. Why don't you use the identity column supported by SQL Server and generate this pseudokey on the fly?

    ;WITH SampleData AS (

    SELECT ID, InsertDateDT = CAST(InsertDate AS DATETIME)

    FROM (VALUES (1,'20120828'), (2,'20120828'), (3,'20120829'),(4,'20120829')) d (ID, InsertDate)

    )

    SELECT

    ID,

    InsertDateDT,

    MyBigintCompositeID = CAST(

    CONVERT(VARCHAR(8),InsertDateDT,112)

    + RIGHT('00000'+CAST(ROW_NUMBER() OVER(PARTITION BY InsertDateDT ORDER BY ID) AS VARCHAR(5)),5)

    AS BIGINT)

    FROM SampleData

    โ€œWrite the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.โ€ - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • This will work for adding one at a time:

    --------------------------------------------------------------

    drop table #test;

    create table #test ( id varchar(13) );

    --------------------------------------------------------------

    declare @id varchar(13), @nextid varchar(13);

    select @id = max(id) from #test;

    select @nextid = case when left(@id, 8) = convert(varchar(8), getdate(), 112)

    then convert(varchar(8), getdate(), 112) +

    right('0000' + cast(cast(substring(@id, 9, 5) as int) +1 as varchar(5)),5)

    else convert(varchar(8), getdate(), 112) + '00001'

    end;

    insert into #test values ( @nextid );

    --------------------------------------------------------------

    select * from #test;

    --------------------------------------------------------------

  • HI ALL

    PLEASE PROVIDE SOME EASY WAY IF YOU KNOW

    THANKS

  • anuj12paritosh (8/28/2012)


    HI ALL

    PLEASE PROVIDE SOME EASY WAY IF YOU KNOW

    THANKS

    The easiest way to achieve that will be switching to SQL2012 and using sequences.

    All others ways will not be easy at all and will always have some issue with concurrency.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (8/28/2012)


    anuj12paritosh (8/28/2012)


    HI ALL

    PLEASE PROVIDE SOME EASY WAY IF YOU KNOW

    THANKS

    The easiest way to achieve that will be switching to SQL2012 and using sequences.

    All others ways will not be easy at all and will always have some issue with concurrency.

    +1

    Luis C.
    General Disclaimer:
    Are you seriously taking the advice and code from someone from the internet without testing it? Do you at least understand it? Or can it easily kill your server?

    How to post data/code on a forum to get the best help: Option 1 / Option 2
  • I am intrigued by ChrisM@Work's comment about possible concurrency issues, so I will submit this suggestion so that he may shoot holes in it based on his statement:

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    IF LEFT(IDENT_CURRENT('#t'), 8) <> CONVERT(VARCHAR(8), GETDATE(), 112)

    BEGIN

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    END

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • laurie-789651 (8/28/2012)


    This will work for adding one at a time:

    --------------------------------------------------------------

    drop table #test;

    create table #test ( id varchar(13) );

    --------------------------------------------------------------

    declare @id varchar(13), @nextid varchar(13);

    select @id = max(id) from #test;

    select @nextid = case when left(@id, 8) = convert(varchar(8), getdate(), 112)

    then convert(varchar(8), getdate(), 112) +

    right('0000' + cast(cast(substring(@id, 9, 5) as int) +1 as varchar(5)),5)

    else convert(varchar(8), getdate(), 112) + '00001'

    end;

    insert into #test values ( @nextid );

    --------------------------------------------------------------

    select * from #test;

    --------------------------------------------------------------

    Ohhhh.... be careful Laurie. A whole lot can happen between the time you get the max id and the time you use it. On high usage systems (or "unlucky" times on low usage systems) you'll end up with duplicate ID's (and dupe errors if the column is unique) with that code. The "obvious fix' of using an explicit transaction will lead to hundreds of deadlocks per day.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • dwain.c (8/28/2012)


    I am intrigued by ChrisM@Work's comment about possible concurrency issues, so I will submit this suggestion so that he may shoot holes in it based on his statement:

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    IF LEFT(IDENT_CURRENT('#t'), 8) <> CONVERT(VARCHAR(8), GETDATE(), 112)

    BEGIN

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    END

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t

    That's seriously clever especially since it solves the multi-row insert problem that most people experience with custom daily dequences but what happens if the number of inserts exceeds 99,999 rows in a day? It won't even warn you that it did a wrap around. And, as fast as it is, there's still the possibility of someone getting in between the DECLARE and the DBCC.

    What about inserts that last from slightly before midnight to slightly after midnight? If you want them to accurately reflect the date they were inserted into the table, you'll be disappointed. Of course, the same would be true of you had a default of GETDATE() on the table.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • anuj12paritosh (8/28/2012)


    hi all,

    i want to generate id column values on the basis of every day.

    suppose table name like test and

    table have column id then value of id column are

    AA

    today is 28-aug-2012 then values are increased after each insert like this

    :-

    table name test

    column name ID

    and values are

    id

    2012082800001

    2012082800002

    ....

    ....

    2012082800002

    and next day it will be on new insert :-

    2012082900001

    2012082900002

    .......

    ........

    and next day it will be on new insert :-

    2012083000001

    2012083000002

    .......

    ........

    I REALLY hope I can talk you and the people you work for out of this idea. At the root of the problem, it's a violation of normal form because you have a column that contains two distinct values... the date of insertion and a very dependent daily sequence number. You also have a growth problem. Yeah... I know you'll say that you'll never go over 99,999 rows in a day but a lot of consultants make a lot of money off of people who thought the same thing.

    And, let me ask... what do you want to do if someone deletes a row?

    I implore you not to use this column for anything except display purposes which also means don't store it in your database. Calculate it at display time like ChrisM did with the understanding that if someone does a delete, the sequence numbers will change.

    If I can't talk you out of it, then wait until the end of each day and calculate the column once for the previous day using code like ChrisM used. Dwain's code is pretty decent and there's a low probability of someone getting in out of sequence but that's not quite the same as saying that it's guaranteed to never dupe a row during the change at midnight.

    --Jeff Moden


    RBAR is pronounced "ree-bar" and is a "Modenism" for Row-By-Agonizing-Row.
    First step towards the paradigm shift of writing Set Based code:
    ________Stop thinking about what you want to do to a ROW... think, instead, of what you want to do to a COLUMN.

    Change is inevitable... Change for the better is not.


    Helpful Links:
    How to post code problems
    How to Post Performance Problems
    Create a Tally Function (fnTally)

  • Jeff Moden (8/28/2012)


    dwain.c (8/28/2012)


    I am intrigued by ChrisM@Work's comment about possible concurrency issues, so I will submit this suggestion so that he may shoot holes in it based on his statement:

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    IF LEFT(IDENT_CURRENT('#t'), 8) <> CONVERT(VARCHAR(8), GETDATE(), 112)

    BEGIN

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    END

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t

    That's seriously clever especially since it solves the multi-row insert problem that most people experience with custom daily dequences but what happens if the number of inserts exceeds 99,999 rows in a day? It won't even warn you that it did a wrap around. And, as fast as it is, there's still the possibility of someone getting in between the DECLARE and the DBCC.

    Hehe. True about something slipping in between the DECLARE and DBCC. But considering you're only expectin 9999 inserts (or hopefully less) per day I'd say it's unlikely. And you can also do this to help avoidance.

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    ,@TodayAsChar VARCHAR(8) = CONVERT(VARCHAR(8), GETDATE(), 112)

    IF LEFT(IDENT_CURRENT('#t'), 8) <> @TodayAsChar

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t

    Thanks Jeff for saying it is clever! I just hope I don't let that go to my head.

    As to >9999 inserts per day - well, we should only allow systems that insert less than that don't you think? ๐Ÿ˜€ Anything more is probably a waste of disk space.


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • So let's really try to get clever (or really obnoxious depending on your perspective :-D) and allow for up to 9,999,999 INSERTs per day. Try this:

    CREATE TABLE #t (ID BIGINT IDENTITY(411470000001, 1)

    ,value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    DECLARE @TodayMidnight INT = CAST(DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) AS INT)

    DECLARE @newseed BIGINT = CAST(CAST(@TodayMidnight AS VARCHAR(5))+'0000000' AS BIGINT)

    IF LEFT(IDENT_CURRENT('#t'), 5) < @TodayMidnight

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT ID=CONVERT(VARCHAR(8), CAST(CAST(LEFT(ID, 5) AS INT) AS DATETIME), 112) + RIGHT(ID,7)

    ,value

    FROM #t

    DROP TABLE #t

    I ran into some really odd anomalies in trying to set this up that I'm at a loss to even explain what they are.

    Edit: Had to make a slight correction and add this:

    What the heck is going on here?

    SELECT CAST(GETDATE() AS INT)

    ,CAST(DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0) AS INT)

    ,GETDATE(), DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • dwain.c (8/28/2012)


    I am intrigued by ChrisM@Work's comment about possible concurrency issues, so I will submit this suggestion so that he may shoot holes in it based on his statement:

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    IF LEFT(IDENT_CURRENT('#t'), 8) <> CONVERT(VARCHAR(8), GETDATE(), 112)

    BEGIN

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    END

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t

    Very creative Dwain! It looks great ... except you have to run a date check every time you insert. I wonder how long RESEED takes on large tables? Might look into that later.

    โ€œWrite the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.โ€ - Gail Shaw

    For fast, accurate and documented assistance in answering your questions, please read this article.
    Understanding and using APPLY, (I) and (II) Paul White
    Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden

  • ChrisM@Work (8/29/2012)


    dwain.c (8/28/2012)


    I am intrigued by ChrisM@Work's comment about possible concurrency issues, so I will submit this suggestion so that he may shoot holes in it based on his statement:

    CREATE TABLE #t (ID BIGINT IDENTITY(201208280001, 1), value INT)

    INSERT INTO #t SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3

    IF LEFT(IDENT_CURRENT('#t'), 8) <> CONVERT(VARCHAR(8), GETDATE(), 112)

    BEGIN

    DECLARE @newseed BIGINT = CAST(CONVERT(VARCHAR(8), GETDATE(), 112)+'0000' AS BIGINT)

    DBCC CHECKIDENT('#t', RESEED, @newseed)

    END

    INSERT INTO #t SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6

    SELECT * FROM #t

    DROP TABLE #t

    Very creative Dwain! It looks great ... except you have to run a date check every time you insert. I wonder how long RESEED takes on large tables? Might look into that later.

    Thanks Chris!

    I was a little concerned about the speed of IDENT_CURRENT actually, but Jeff seems to suggest it should be pretty quick.

    I have to confess that I needed to look up the syntax for this as I rarely work with IDENTITY columns. It's good to know what can be done though, so then Google is your friend. ๐Ÿ˜€


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

  • Had to make a slight correction to my prior post and add a question.


    My mantra: No loops! No CURSORs! No RBAR! Hoo-uh![/I]

    My thought question: Have you ever been told that your query runs too fast?

    My advice:
    INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?
    The path of least resistance can be a slippery slope. Take care that fixing your fixes of fixes doesn't snowball and end up costing you more than fixing the root cause would have in the first place.

    Need to UNPIVOT? Why not CROSS APPLY VALUES instead?[/url]
    Since random numbers are too important to be left to chance, let's generate some![/url]
    Learn to understand recursive CTEs by example.[/url]
    [url url=http://www.sqlservercentral.com/articles/St

Viewing 15 posts - 1 through 15 (of 17 total)

You must be logged in to reply to this topic. Login to reply