Results 1 to 8 of 8

Thread: [RESOLVED] Tough SQL (like a cross table) -- SQL Server 2008R2

  1. #1

    Thread Starter
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Resolved [RESOLVED] Tough SQL (like a cross table) -- SQL Server 2008R2

    Hi guys

    I using SQL Server 2008R2 and need to convert a vertical table (Key-Values pairs) into a standard looking SQL Server table.....

    The data comes into the db like this

    ReportDumpId Int Indentity
    ReportId Int
    KeyName NVARCHAR(2000)
    KevyValue NVARCHAR(2000)
    KeyType NVARCHAR(255)


    and a sample of the data:

    ReportDumpId ReportId ItemId KeyName KeyValue KeyType
    756 49415 2237099 referencenumber 2237099 notype
    757 49415 2237099 referencenumberusrprefix USR2237099 notype
    758 49415 2237099 category Academic (professor, student, researcher) notype
    759 49415 2237099 attendeerecordurl https://www.eiseverywhere.com/ereg/r...QOt757xQ%3D%3D attendee
    760 49415 2237099 registered 2011-07-19 notype
    761 49415 2237099 registereddateandtime 2011-07-19 12:20:56 notype
    762 49415 2237099 registeredby attendee notype
    763 49415 2237099 registrationstatus Confirmed notype
    764 49415 2237099 approvalstatus Approved notype
    765 49415 2237099 modified 2011-07-19 notype


    What I ultimatlely need is something that looks like this:
    ItemId referencenumber referencenumberusrprefix and so on....
    2237099 2237099 USR2237099


    Any one got any ideas?

    I was thinking of a cross tabl but can't seem to get my head around it.
    Last edited by GaryMazzone; Sep 19th, 2011 at 09:55 AM. Reason: Fix spelling in title
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  2. #2
    Code Monkey wild_bill's Avatar
    Join Date
    Mar 2005
    Location
    Montana
    Posts
    2,993

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    You could join the table to itself
    Code:
    declare @temp table(ReportDumpId int, ReportId int, ItemId int, KeyName nvarchar(2000), KeyValue nvarchar(2000), KeyType nvarchar(255))
    
    INSERT INTO @temp(ReportDumpId, ReportId, ItemId, KeyName, KeyValue, KeyType) VALUES
    (756, 49415, 2237099, 'referencenumber', '2237099', 'notype'),
    (757, 49415, 2237099, 'referencenumberusrprefix', 'USR2237099', 'notype'),
    (758, 49415, 2237099, 'category Academic', '(professor, student, researcher)', 'notype'),
    (759, 49415, 2237099, 'attendeerecordurl', 'https://www.eiseverywhere.com/ereg/r...QOt757xQ%3D%3D', 'attendee'),
    (760, 49415, 2237099, 'registered', '2011-07-19', 'notype'),
    (761, 49415, 2237099, 'registereddateandtime', '2011-07-19 12:20:56', 'notype'),
    (762, 49415, 2237099, 'registeredby', 'attendee', 'notype'),
    (763, 49415, 2237099, 'registrationstatus', 'Confirmed', 'notype'),
    (764, 49415, 2237099, 'approvalstatus', 'Approved', 'notype'),
    (765, 49415, 2237099, 'modified', '2011-07-19', 'notype')
    
    
    select t1.itemid, t1.KeyValue as 'referencenumber', t2.KeyValue as 'referencenumberusrprefix'
    from @temp t1
    inner join @temp t2 on t1.ItemId = t2.ItemId and t2.KeyName = 'referencenumberusrprefix'
    where t1.KeyName = 'referencenumber'
    That is the very essence of human beings and our very unique capability to perform complex reasoning and actually use our perception to further our understanding of things. We like to solve problems. -Kleinma

    Does your code in post #46 look like my code in #45? No, it doesn't. Therefore, wrong is how it looks. - jmcilhinney

  3. #3

    Thread Starter
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    The problem is that there are an unknown number of KeyValue pairs (this on in the example there are 117 pairs).

    Writing 117 joins will be an issue.

    also the table that holds the temp data is as show Identity number for a row, the reportId this is from, the fieldName , the fieldvalue (the KeyValue pair) and then a KeyType (I might use this or not yet)
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  4. #4

    Thread Starter
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    OK this is nasty but it does work and converts the vertical table of Key Value pairs to a normal looking table:

    sql Code:
    1. SET NOCOUNT ON;
    2.  
    3. IF EXISTS (SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'tempTestTable')
    4.     BEGIN
    5.         DROP TABLE tempTestTable
    6.     END
    7.  
    8. IF EXISTS (SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'tempColumnNames')
    9.     BEGIN
    10.         DROP TABLE tempColumnNames
    11.     END
    12.  
    13. CREATE TABLE tempColumnNames (
    14.     CoumnName VARCHAR(2000)
    15.     )
    16.  
    17. DECLARE @ItemId INT
    18. DECLARE @sql NVARCHAR(MAX) ,
    19.         @sqlSelect NVARCHAR(MAX) ,
    20.         @ColumnName AS VARCHAR(2000)
    21.        
    22. DECLARE c1 CURSOR FORWARD_ONLY READ_ONLY FOR
    23.     SELECT TOP 1 ItemId FROM eTouchs.tempReportDump  
    24.         ORDER BY 1
    25.  
    26. OPEN c1
    27. FETCH NEXT FROM c1 INTO @ItemId
    28. WHILE @@FETCH_STATUS = 0
    29.     BEGIN
    30.         SET @sql = 'Create Table tempTestTable (ItemId BIGINT, '
    31.         SET @sqlSelect = 'SELECT ItemId, '
    32.         --print @ItemId
    33.         DECLARE c2 CURSOR Forward_only Read_only FOR
    34.             SELECT KeyName FROM eTouchs.tempReportDump
    35.                 WHERE ItemId = @ItemId
    36.                 ORDER BY KeyName
    37.         OPEN c2
    38.         FETCH NEXT FROM c2 INTO @ColumnName
    39.         WHILE @@FETCH_STATUS = 0
    40.             BEGIN
    41.                 SET @sql = @sql + @columnName + N' VARCHAR(MAX) ,'
    42.                 INSERT INTO tempColumnNames VALUES ( @ColumnName )
    43.                 SET @sqlSelect = @sqlSelect + @ColumnName + ', '
    44.                 FETCH NEXT FROM c2 INTO @ColumnName
    45.             END
    46.         CLOSE c2
    47.         DEALLOCATE c2
    48.         SET @sql = SUBSTRING(@sql,1,LEN(@sql) -1) + N')'
    49.         SET @sqlSelect = SUBSTRING (@sqlSelect ,1,LEN(@sqlSelect) -1 ) + N' FROM eTouchs.tempReportDump Order By ItemId'
    50.         FETCH NEXT FROM c1 INTO @ItemId
    51.     END    
    52. CLOSE c1
    53. DEALLOCATE c1
    54. --Creates the temp table to hold results
    55. EXECUTE sp_executesql @sql
    56.  
    57. --Now insert a Qnique set of itemIds
    58. INSERT INTO tempTestTable (ItemId) SELECT DISTINCT ItemId FROM eTouchs.tempReportDump
    59.  
    60. --Now we update
    61. DECLARE @updateSQL NVARCHAR(MAX) ,
    62.         @keyVal NVARCHAR(4000)
    63.        
    64. DECLARE c1 CURSOR FORWARD_ONLY READ_ONLY FOR
    65.     SELECT DISTINCT ItemId FROM eTouchs.tempReportDump
    66.  
    67. OPEN c1
    68. FETCH NEXT FROM c1 INTO @ItemId
    69. WHILE @@FETCH_STATUS = 0
    70.     BEGIN
    71.         --Now we need to build up an update statement
    72.         DECLARE c2 CURSOR FORWARD_ONLY READ_ONLY FOR
    73.             SELECT CoumnName FROM tempColumnNames
    74.         OPEN c2
    75.         FETCH NEXT FROM c2 INTO @columnName
    76.         WHILE @@FETCH_STATUS = 0
    77.         BEGIN
    78.             SELECT @keyVal = KeyValue FROM eTouchs.tempReportDump WHERE ItemId = @ItemId AND KeyName = @ColumnName
    79.             SET @updateSQL = 'UPDATE tempTestTable Set '+ @columnName + ' = ''' + @keyVal + ''' WHERE ItemId = ' + CONVERT(NVARCHAR(100),@itemId)      
    80.             BEGIN TRY
    81.                 BEGIN
    82.                     EXECUTE sp_executesql @updateSQL
    83.                 END
    84.             END TRY
    85.             BEGIN CATCH
    86.                 BEGIN
    87.                     PRINT @updateSQL
    88.                     PRINT @@ERROR
    89.                 END
    90.             END CATCH
    91.             FETCH NEXT FROM c2 INTO @columnName
    92.         END
    93.         CLOSE c2
    94.         DEALLOCATE c2  
    95.         FETCH NEXT FROM c1 INTO @ItemId
    96.     END
    97. CLOSE c1
    98. DEALLOCATE c1
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  5. #5
    Code Monkey wild_bill's Avatar
    Join Date
    Mar 2005
    Location
    Montana
    Posts
    2,993

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    I go close using XML, but there is no select * from @xml, so I got stuck. It might be useful, so I thought I would post it.
    Code:
    declare @temp table(ReportDumpId int, ReportId int, ItemId int, KeyName nvarchar(2000), KeyValue nvarchar(2000), KeyType nvarchar(255))
    
    INSERT INTO @temp(ReportDumpId, ReportId, ItemId, KeyName, KeyValue, KeyType) VALUES
    (756, 49415, 2237099, 'referencenumber', '2237099', 'notype'),
    (757, 49415, 2237099, 'referencenumberusrprefix', 'USR2237099', 'notype'),
    (758, 49415, 2237099, 'category', 'Academic (professor, student, researcher)', 'notype'),
    (759, 49415, 2237099, 'attendeerecordurl', 'https://www.eiseverywhere.com/ereg/r...QOt757xQ%3D%3D', 'attendee'),
    (760, 49415, 2237099, 'registered', '2011-07-19', 'notype'),
    (761, 49415, 2237099, 'registereddateandtime', '2011-07-19 12:20:56', 'notype'),
    (762, 49415, 2237099, 'registeredby', 'attendee', 'notype'),
    (763, 49415, 2237099, 'registrationstatus', 'Confirmed', 'notype'),
    (764, 49415, 2237099, 'approvalstatus', 'Approved', 'notype'),
    (765, 49415, 2237099, 'modified', '2011-07-19', 'notype')
    
    declare @work varchar(max)
    	--create single row of data
    	set @work = 
    	(select Tag, Parent, [ROOT!1!ReportId],[ROOT!1!ItemId],[CHILD!2!KeyName],[CHILD!2!KeyValue] From 
    (select distinct 1 AS Tag
    		,NULL as Parent
    		,ReportId as [ROOT!1!ReportId]
    		,ItemId as [ROOT!1!ItemId]
    		,NULL as [CHILD!2!KeyName]
    		,NULL as [CHILD!2!KeyValue]
    	from @temp
    	UNION ALL
    	select 2 as Tag
    		,1 as Parent
    		,ReportId 
    		,ItemId
    		,KeyName
    		,KeyValue
    	FROM @temp) as t
    	FOR XML EXPLICIT)
    	
    	--tweak xml
    	set @work = REPLACE(@work,'CHILD KeyName="','')
    	set @work = REPLACE(@work,'" KeyValue',' KeyValue')
    	
    	select cast(@work as xml)
    That is the very essence of human beings and our very unique capability to perform complex reasoning and actually use our perception to further our understanding of things. We like to solve problems. -Kleinma

    Does your code in post #46 look like my code in #45? No, it doesn't. Therefore, wrong is how it looks. - jmcilhinney

  6. #6
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    wait.... hold on.... hang on... I think I might have something here...
    Take a look at the stuff function

    I discovered it while looking for a solution to pivot tables dynamically... an example of how it works:
    Code:
    DECLARE @cols NVARCHAR(2000)
    SELECT  @cols = STUFF(( SELECT DISTINCT TOP 100 PERCENT
                                    '],[' + t2.ColName
                            FROM    Table1 AS t2
                            ORDER BY '],[' + t2.ColName
                            FOR XML PATH('')
                          ), 1, 2, '') + ']'
    from here: http://www.simple-talk.com/community.../14/37265.aspx

    I just reread the posting... you need to pivot... take a look at the link I jsut posted... it might be what you need.. a dynamic pivot table... the down side is that it means dynamic SQL... so you'll want to be sure of the data you're toying with. It's not an ideal solution, but it does work... I was using it up to about a week ago when I realized I was over complicating something that should have been simple.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  7. #7

    Thread Starter
    A SQL Server fool GaryMazzone's Avatar
    Join Date
    Aug 2005
    Location
    Dover,NH
    Posts
    7,493

    Re: Tough SQL (like a cross table) -- SQL Server 2008R2

    Here is what I came out with in the end:

    sql Code:
    1. DECLARE @cols NVARCHAR(MAX) ,
    2.         @query NVARCHAR(MAX) ,
    3.         @cols2 NVARCHAR(MAX) ,
    4.         @query2 NVARCHAR(MAX)
    5.  
    6. SELECT  
    7.     @cols = ISNULL(@cols + ', ', '') + QUOTENAME(tc.keyname)
    8. FROM
    9.     eTouchs.tempReportDump tc
    10. WHERE tc.KeyType != 'question'
    11. GROUP BY KeyName
    12. ORDER BY KeyName
    13.  
    14.  
    15. SELECT  
    16.     @cols2 = ISNULL(@cols2 + ', ', '') + QUOTENAME(tc.keyname)
    17. FROM
    18.     eTouchs.tempReportDump tc
    19. WHERE tc.KeyType = 'question'
    20. GROUP BY KeyName
    21. ORDER BY KeyName
    22.  
    23.  
    24. SET @query = N'SELECT  ItemId, ' + @cols + '
    25. FROM (
    26.     select
    27.        ItemId,
    28.        KeyName,
    29.        KeyValue
    30.     from eTouchs.tempReportDump) srcData  
    31.     PIVOT (
    32.        max(KeyValue)
    33.        FOR KeyName IN
    34.        ( ' + @cols + ' )
    35.        ) AS pvt
    36. ORDER BY  ItemId';
    37.  
    38.  
    39. SET @query2 = N'SELECT  ItemId, ' + @cols2 + '
    40. FROM (
    41.     select
    42.        ItemId,
    43.        KeyName,
    44.        KeyValue
    45.     from eTouchs.tempReportDump) srcData  
    46.     PIVOT (
    47.        max(KeyValue)
    48.        FOR KeyName IN
    49.        ( ' + @cols2 + ' )
    50.        ) AS pvt
    51. ORDER BY ItemId';
    52.  
    53. --This is non-question fields
    54. EXECUTE sp_executesql @query
    55. --This is question fields
    56. EXECUTE sp_executesql @query2

    Yes the field names can change at any time. The number of fields can change at any time. Isn't standardazation great.
    Sometimes the Programmer
    Sometimes the DBA

    Mazz1

  8. #8
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    34,687

    Re: [RESOLVED] Tough SQL (like a cross table) -- SQL Server 2008R2

    Yup... looks very similar to the SQL I was working with... I had the added bonus that within my pivot, I was summing (budgets) ... so I had to have two cols as well... one for the cols themselves .... and one for the group by ... that was a joy....

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width