Can someone help with a TSQL date sorting issue?

  • I would like to retrieve data for all the fields listed in the query below. The problem is that I would like to partition Collection into 3 date fields then sort the columns by the most Resent date (DESC Order)

    See query and sample output below:

    SELECT

    Name,

    MeterId,

    Collection Date,

    Collection Amount,

    MeterNumber,

    Blockface

    FROM dbo.CollectionSummaries C WITH(NOLOCK)

    JOIN Meters M WITH(NOLOCK) ON M.MeterId = C.MeterId

    LEFT JOIN RouteAssignments RA WITH(NOLOCK) ON RA.MeterId = M.MeterId

    LEFT JOIN [Routes] R WITH(NOLOCK) ON R.RouteId = RA.RouteId

    JOIN RouteTypes RT WITH(NOLOCK) ON RT.DisplayName = 'Collection'

    JOIN dbo.Blockfaces B WITH(NOLOCK) ON B.BlockFaceId = M.BlockFaceId

    JOIN dbo.Streets S WITH(NOLOCK) ON S.StreetId = B.StreetId

    WHERE

    AND R.RouteTypeId = 1

    Group by Name,

    MeterId,

    CollectionDate,

    MeterNumber,

    Blockface

    Order by CollectionDate DESC

    Sample Output

    Column #1 Column#2 (Column#3

    CollectionDate1 CollectionDate2 CollectionDate3

    2013/04/15 2013/03/01 2012/12/14

    2013/04/14 2013/02/10 2012/11/02

    2013/04/02 2013/01/30 2012/11/01

    Any suggestions would be greatly appreciated.

    Thanks

  • The first suggestion I would make is that, in the future, you help us help you. Please see the first link in my signature line for a short article on the best way to do that. I'll take care of the readily consumable data this time, though, because you're kinda new here.

    Here's the solution to your problem. The details are in the comments in the code.

    WITH

    cteEnumerate AS

    (

    SELECT rs.CollectionDate

    , RowNum = ROW_NUMBER() OVER (ORDER BY rs.CollectionDate DESC)-1

    FROM ( --=== This represents your result set

    SELECT '2013/04/14' UNION ALL

    SELECT '2012/12/14' UNION ALL

    SELECT '2013/04/02' UNION ALL

    SELECT '2013/03/01' UNION ALL

    SELECT '2012/11/02' UNION ALL

    SELECT '2013/02/10' UNION ALL

    SELECT '2013/01/30' UNION ALL

    SELECT '2013/04/15' UNION ALL

    SELECT '2012/11/01'

    ) rs (CollectionDate)

    ) --=== Pivot the data using Modulo to locate the columns

    -- and Integer Division to locate the rows

    SELECT [Column #1] = MAX(CASE WHEN RowNum%3 = 0 THEN CollectionDate ELSE '' END)

    , [Column #2] = MAX(CASE WHEN RowNum%3 = 1 THEN CollectionDate ELSE '' END)

    , [Column #3] = MAX(CASE WHEN RowNum%3 = 2 THEN CollectionDate ELSE '' END)

    FROM cteEnumerate

    GROUP BY RowNum/3

    ORDER BY RowNum/3

    ;

    You're also going to need some work on your original query. It's not likely that it works correctly as is because of the spaces in some of the names of columns in the SELECT list.

    --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)

  • Thanks for your help and suggessions.

    Your code is very close to resolving my sorting issue. However, I am still having problems getting it to work so I am taking your suggession and including the table structure with insert statements and sample output.

    I would like to sort the date field in DESC order sequententially; then partition the date/amount columns into 6 columns (3 date and 3 amount columns). See example below: I will send also send an attachment - the format changed.

    Table Structure

    CREATE TABLE #CollectionSummaries(

    [Id] [int] IDENTITY(1,1) NOT NULL,

    [MeterId] [int] NULL,

    [CollectionTime] [datetime] NOT NULL,

    [TotalAmount] [decimal](8, 2) NOT NULL,

    [UniqueSpaceId] [nvarchar](50) NULL

    )

    --CONSTRAINT [PK_CollectionSummaries] PRIMARY KEY CLUSTERED

    Insert Statement

    INSERT INTO #CollectionSummaries

    ([MeterId]

    ,[CollectionTime]

    ,[TotalAmount]

    ,[UniqueSpaceId])

    VALUES(

    6146,'2013-04-15 09:20:08.000',12.34,'26254',

    6146,'2013-04-15 08:20:08.000',12.34,'26254',

    997,'2013-04-08 23:59:31.000',0.50,'CB2397',

    997,'2013-03-07 23:17:12.000',0.50,'CB2397',

    4351,'2013-03-01 22:59:46.000',4.07,'ED263',

    4313,'2013-02-22 22:55:30.000',4.05,'ED647',

    997,'2013-02-08 22:24:01.000',0.50,'CB2397',

    2644,'2013-01-25 22:10:14.000',3.14,'CB3077',

    5026,'2013-01-21 21:06:54.000',15.35,'LT491',

    4907,'2012-12-20 20:53:09.000',0.80,'LT379',

    4415,'2012-12-08 20:30:38.000',1.25,'ED342',

    224,'2012-11-07 20:24:11.000',14.52,'CB3511',

    4835,'2012-11-01 20:18:42.000',25.45,'LT8A')

    Sample OutPut[/u]

    collectionDate1 TotalAmount1 collectionDate2 TotalAmount2collectionDate3 TotalAmount3

    4/15/2013 1.50 11/25/2012 2.0010/25/2012 7.00

    3/1/2013 22.50 11/17/2012 4.0010/21/2012 9.00

    2/1/2013 10.00 11/11/2012 3.0010/15/2012 11.00

    1/1/2013 32.50 11/1/2012 5.0010/10/2012 16.00

    12/1/2012 11.00 10/27/2012 6.0010/1/2012 17.00

  • You haven't explained how you are grouping and combining items for your results.

    You have datetime values as well. Sorting these will not put 2013-04-15 09:20:08.000 and 2013-04-15 08:20:08.000 in the same bucket. They would be two rows. Are you combining on date only?

  • See query with groupings below. I have also attached an excel spreadsheet with the sample output.

    SELECT

    Name as StreetName,

    MeterId,

    CollectionDate,

    CollectionAmount,

    SpaceUniqueID as MeterNumber,

    Blockface

    FROM dbo.CollectionSummaries C WITH(NOLOCK)

    JOIN Meters M WITH(NOLOCK) ON M.MeterId = C.MeterId

    LEFT JOIN RouteAssignments RA WITH(NOLOCK) ON RA.MeterId = M.MeterId

    LEFT JOIN [Routes] R WITH(NOLOCK) ON R.RouteId = RA.RouteId

    JOIN RouteTypes RT WITH(NOLOCK) ON RT.DisplayName = 'Collection'

    JOIN dbo.Blockfaces B WITH(NOLOCK) ON B.BlockFaceId = M.BlockFaceId

    JOIN dbo.Streets S WITH(NOLOCK) ON S.StreetId = B.StreetId

    WHERE

    AND R.RouteTypeId = 1

    Group by

    Name,

    MeterId,

    CollectionDate,

    SpaceUniqueID ,

    Blockface

    Order by CollectionDate DESC

  • Apologies for my previous post. It was getting late and I didn't notice the sort order. Although the following will look identical to my previous post to the casual observer, please note that I swapped the Integer Divides and the Modulo to produce the correct sort order.

    WITH

    cteEnumerate AS

    (

    SELECT rs.CollectionDate

    , RowNum = ROW_NUMBER() OVER (ORDER BY rs.CollectionDate DESC)-1

    FROM ( --=== This represents your result set

    SELECT '2013/04/14' UNION ALL

    SELECT '2012/12/14' UNION ALL

    SELECT '2013/04/02' UNION ALL

    SELECT '2013/03/01' UNION ALL

    SELECT '2012/11/02' UNION ALL

    SELECT '2013/02/10' UNION ALL

    SELECT '2013/01/30' UNION ALL

    SELECT '2013/04/15' UNION ALL

    SELECT '2012/11/01'

    ) rs (CollectionDate)

    ) --=== Pivot the data using Modulo to locate the columns

    -- and Integer Division to locate the rows

    SELECT [Column #1] = MAX(CASE WHEN RowNum/3 = 0 THEN CollectionDate ELSE '' END)

    , [Column #2] = MAX(CASE WHEN RowNum/3 = 1 THEN CollectionDate ELSE '' END)

    , [Column #3] = MAX(CASE WHEN RowNum/3 = 2 THEN CollectionDate ELSE '' END)

    FROM cteEnumerate

    GROUP BY RowNum%3

    ORDER BY RowNum%3

    ;

    Results:

    Column #1Column #2Column #3

    2013/04/152013/03/012012/12/14

    2013/04/142013/02/102012/11/02

    2013/04/022013/01/302012/11/01

    --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)

  • leonie6214 (4/16/2013)


    See query with groupings below. I have also attached an excel spreadsheet with the sample output.

    SELECT

    Name as StreetName,

    MeterId,

    CollectionDate,

    CollectionAmount,

    SpaceUniqueID as MeterNumber,

    Blockface

    FROM dbo.CollectionSummaries C WITH(NOLOCK)

    JOIN Meters M WITH(NOLOCK) ON M.MeterId = C.MeterId

    LEFT JOIN RouteAssignments RA WITH(NOLOCK) ON RA.MeterId = M.MeterId

    LEFT JOIN [Routes] R WITH(NOLOCK) ON R.RouteId = RA.RouteId

    JOIN RouteTypes RT WITH(NOLOCK) ON RT.DisplayName = 'Collection'

    JOIN dbo.Blockfaces B WITH(NOLOCK) ON B.BlockFaceId = M.BlockFaceId

    JOIN dbo.Streets S WITH(NOLOCK) ON S.StreetId = B.StreetId

    WHERE

    AND R.RouteTypeId = 1

    Group by

    Name,

    MeterId,

    CollectionDate,

    SpaceUniqueID ,

    Blockface

    Order by CollectionDate DESC

    Heh... you do make it hard to help you. You keep posting a query that we have no data for, your previous "readily consumable data" code doesn't actually work because you didn't test it before you posted it, you've dramatically changed the requirements of the problem, and you've not explained how you want to list the output if there are more or less than 3 rows per MeterID.

    Slow down and line up your ducks. We can't hit the hole of a rolling donut that we can't see. Post back when you're ready. 😉

    --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)

  • I am sorry but I was not aware of the rules. However, I did include the table structure w/insert statements; I also attached an excel spreadsheet with the desired output in the previous post.

    Anyway, you may have resolved my issue. I will test it and reply to you again.

    Thanks for you help.

    leonie6214

  • leonie6214 (4/16/2013)


    I am sorry but I was not aware of the rules. However, I did include the table structure w/insert statements; I also attached an excel spreadsheet with the desired output in the previous post.

    Anyway, you may have resolved my issue. I will test it and reply to you again.

    Thanks for you help.

    leonie6214

    Not rules. Just trying to help and the requirements changed and the data load didn't work.

    Glad you got it to work, though.

    --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)

  • Hi Jeff ,

    I was able to resolve my sorting issue with your code example.

    Thanks so much for your help.

    Leonie6214

  • It would be great if you posted the solution, in case anyone else has a similar issue.

  • I know I am bit late to the game on this one but since nobody else mentioned it, you need to be careful that NOLOCK hint. Do you know why you need it? Do you know some of the pitfalls of that hint?

    http://blogs.msdn.com/b/davidlean/archive/2009/04/06/sql-server-nolock-hint-other-poor-ideas.aspx

    http://www.jasonstrate.com/2012/06/the-side-effect-of-nolock/[/url]

    _______________________________________________________________

    Need help? Help us help you.

    Read the article at http://www.sqlservercentral.com/articles/Best+Practices/61537/ for best practices on asking questions.

    Need to split a string? Try Jeff Modens splitter http://www.sqlservercentral.com/articles/Tally+Table/72993/.

    Cross Tabs and Pivots, Part 1 – Converting Rows to Columns - http://www.sqlservercentral.com/articles/T-SQL/63681/
    Cross Tabs and Pivots, Part 2 - Dynamic Cross Tabs - http://www.sqlservercentral.com/articles/Crosstab/65048/
    Understanding and Using APPLY (Part 1) - http://www.sqlservercentral.com/articles/APPLY/69953/
    Understanding and Using APPLY (Part 2) - http://www.sqlservercentral.com/articles/APPLY/69954/

Viewing 12 posts - 1 through 11 (of 11 total)

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