SQL Server Developer Center > SQL Server Forums > Transact-SQL > Create a view based on the exiting table ?
Ask a questionAsk a question
 

AnswerCreate a view based on the exiting table ?

  • Tuesday, November 03, 2009 2:45 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi guys,

    i am stuck on a one issues these days, like i have a table like bellow

    Id     DocId    FieldName              FieldValue
    1       201       LastPrintPerson      Dominic lorenzo
    2       201       LastPrintDate         01/02/2007
    3       204       LastPrintPerson      Gomez Hwang
    4       204       LastPrintDate         01/07/2008


    Now what i need to do is i need to create a view based on that above table structure like bellow,

    DocId    LastPrintPerson        LastPrintDate
    201       Dominic lorenzo       01/02/2007
    204       Gomez Hwang          01/07/2008



    any idea to do this ?

    thanks
    regards
    sukavi


Answers

  • Tuesday, November 03, 2009 3:06 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Here is another way

    DECLARE @t TABLE(id INT IDENTITY(1,1),DocID INT,FieldName VARCHAR(MAX),FieldValue VARCHAR(MAX))
    
    INSERT INTO @t (DocID,FieldName,Fieldvalue)
    SELECT 201,'LastPrintPerson','Dominic lorenzo' UNION ALL
    SELECT 201,'LastPrintDate','01/02/2007' UNION ALL
    SELECT 204 ,'LastPrintPerson','Gomez Hwang' UNION ALL
    SELECT 204,'LastPrintDate','01/07/2008'
    
    SELECT docid
    ,MAX(CASE WHEN row = 1 THEN fieldvalue ELSE '' END) AS 'LastPrintPerson'
    ,MAX(CASE WHEN row = 2 THEN fieldvalue ELSE '' END) AS 'LastPrintDate'
    FROM 
    (
    	SELECT docid,fieldname,fieldvalue,ROW_NUMBER() OVER(PARTITION BY docid ORDER BY docid) AS row
    		FROM @t
    ) AS x
    GROUP BY docid
    

    Abdallah, PMP, MCTS
    • Marked As Answer bysukavi Tuesday, November 03, 2009 3:40 PM
    •  
  • Thursday, November 05, 2009 5:26 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Sukavi

    58000 records is not much. Are you sure you have proper indexes on your table?
    If you post all the query then we might be able to help you.


    Abdallah, PMP, ITIL, MCTS
    • Marked As Answer bysukavi Thursday, November 05, 2009 5:43 PM
    •  

All Replies

  • Tuesday, November 03, 2009 3:01 PMJohn Ang. Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Has Code
    Hi,

    Try this:

    with cte as (
         select 1 as ID, 201 as DocID, 'LastPrintPerson' as FieldName, 'Dominic lorenzo' as FieldValue
         union all
         select 2 as ID, 201 as DocID, 'LastPrintDate' as FieldName, '01/02/2007' as FieldValue
         union all
         select 3 as ID, 204 as DocID, 'LastPrintPerson' as FieldName, 'Gomez Hwang' as FieldValue
         union all
         select 4 as ID, 204 as DocID, 'LastPrintDate' as FieldName, '01/07/2008' as FieldValue
    )
    select
         c1.DocID
    ,    c1.FieldValue as LastPrintPerson
    ,    c2.FieldValue as LastPrintDate
    from cte c1
    join cte c2 on
       c1.DocID = c2.DocID  
    where
         c1.FieldName = 'LastPrintPerson'
         and c2.FieldName = 'LastPrintDate'
    
    


    Regards,
    John
  • Tuesday, November 03, 2009 3:06 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     AnswerHas Code

    Here is another way

    DECLARE @t TABLE(id INT IDENTITY(1,1),DocID INT,FieldName VARCHAR(MAX),FieldValue VARCHAR(MAX))
    
    INSERT INTO @t (DocID,FieldName,Fieldvalue)
    SELECT 201,'LastPrintPerson','Dominic lorenzo' UNION ALL
    SELECT 201,'LastPrintDate','01/02/2007' UNION ALL
    SELECT 204 ,'LastPrintPerson','Gomez Hwang' UNION ALL
    SELECT 204,'LastPrintDate','01/07/2008'
    
    SELECT docid
    ,MAX(CASE WHEN row = 1 THEN fieldvalue ELSE '' END) AS 'LastPrintPerson'
    ,MAX(CASE WHEN row = 2 THEN fieldvalue ELSE '' END) AS 'LastPrintDate'
    FROM 
    (
    	SELECT docid,fieldname,fieldvalue,ROW_NUMBER() OVER(PARTITION BY docid ORDER BY docid) AS row
    		FROM @t
    ) AS x
    GROUP BY docid
    

    Abdallah, PMP, MCTS
    • Marked As Answer bysukavi Tuesday, November 03, 2009 3:40 PM
    •  
  • Tuesday, November 03, 2009 3:18 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi 
    it worked in both wasy ..thank you two lot,
    but i have a small question to ask from "Abdshall"
    basically what this line means ?

    "OVER(PARTITION BY docid ORDER BY docid) AS row     "   i never used this before..could you please explain me bit me on this ?

    thanks
    regards
    sukavi


  • Tuesday, November 03, 2009 3:34 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    This line  ROW_NUMBER() OVER(PARTITION BY docid ORDER BY docid) AS row is a ranking function that partitions the result based on the docid .

    Run the following code by itself and you will see exactly what it does. You can change @t to your table name if you like.

    SELECT docid,fieldname,fieldvalue,ROW_NUMBER() OVER(PARTITION BY docid ORDER BY docid) AS row
    FROM @t

    Abdallah, PMP, MCTS
  • Tuesday, November 03, 2009 3:43 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi "Abdshall "

    Thank you lot i understood nicely with your example...

    great work mate.....

    regards
    sukavi .
  • Wednesday, November 04, 2009 4:19 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Abdshall,

    i have got a small issue on your solution, according to the solution you provided ,when evever we add a new RowField we have to go and chage our SQL in order effect the changes,

    for example if we add a new row like "LastModifiedDate" ,
     
    Id     DocId    FieldName              FieldValue
    1       201       LastPrintPerson      Dominic lorenzo
    2       201       LastPrintDate         01/02/2007
    3       201       LastModifiedDate   01/02/2006
    4       204       LastPrintPerson      Gomez Hwang
    5       204       LastPrintDate         01/07/2008
    6       201       LastModifiedDate   01/02/2007

    then we have to change our SQL like bellow
    ,
    ================================================
    SELECT docid
    ,MAX(CASE WHEN row = 1 THEN fieldvalue ELSE '' END) AS 'LastPrintPerson'
    ,MAX(CASE WHEN row = 2 THEN fieldvalue ELSE '' END) AS 'LastPrintDate'
    ,MAX(CASE WHEN row = 3 THEN fieldvalue ELSE '' END) AS 'LastModifiedDate'

    FROM
    (
    SELECT docid,fieldname,fieldvalue,ROW_NUMBER() OVER(PARTITION BY docid ORDER BY docid) AS row
    FROM @t
    ) AS x
    GROUP BY docid
    ===============================================

    so instead of modifying the SQL each time ,is there any solution on this issue like writing a generic (dynamic) SQL so that we don't need to change our SQL each time, problem is my Table Data get change most of the time....so i have to change the SQL alone with that modification, bit of a pain .

    any idea ,

     

    regards

    sukavi

     

  • Wednesday, November 04, 2009 4:24 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
  • Wednesday, November 04, 2009 4:37 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi "Abdshall"
    thanks for the quick reply....i am still working on this...basically trying to understand the articles u providd me...when i find the answer for this i will post it here....so this might be usefull for others.
    thanks
    regards
    sukavi
  • Wednesday, November 04, 2009 4:43 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I would suggest you start with the last one as it starts from regular pivot(in case you never worked with them) until it gets to the dynamic pivot.
    Good luck
    Abdallah, PMP, MCTS
  • Thursday, November 05, 2009 4:50 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi Abdshall,
    i am trying from yesterday ,but still i am stuck.....i tried PIVOT solution.getting errors when i am trying using SUM ,thing is my "FieldValue" is a Varchar data type ..so it won't allow me to SUM up the results based on the Varchar datatype

    eg : i tried in this way

    DECLARE

     

    @t TABLE(id INT IDENTITY(1,1),DocID INT,FieldName VARCHAR(MAX),FieldValue VARCHAR(MAX))

    INSERT

     

    INTO @t (DocID,FieldName,Fieldvalue)

    SELECT

     

    201,'LastPrintPerson','Dominic lorenzo' UNION ALL

    SELECT

     

    201,'LastPrintDate','01/02/2007' UNION ALL

    SELECT

     

    204 ,'LastPrintPerson','Gomez Hwang' UNION ALL

    SELECT

     

    204,'LastPrintDate','01/07/2008'

     

    select

     

    *

    from

    (

     

    select

    DocID

    , FieldName, Fieldvalue

     

    from @t

    )

     

    DataTable

    PIVOT

    (

     

    SUM(Fieldvalue)

     

    FOR FieldName

     

    IN (

    [LastPrintPerson]

     

    )

    )

     

    PivotTable

     



    but i am getting bellow error :

    Operand data type varchar(max) is invalid for sum operator.

    any solution on this?

     

     


    thnaks
    regards
    sukavi

  • Thursday, November 05, 2009 5:01 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Change the SUM to COUNT and your query will work.


    Abdallah, PMP, ITIL, MCTS
  • Thursday, November 05, 2009 5:11 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi thanks for the quick reply,
    if i use Count ...it will only show me the number value, alwasys 1 if there is any values on it otherwise 0 ,
    like :

    docid    lastprintperson
    201       1
    204       1

    but i really need to see the actual data ...
    like  bellow ,

    docid    lastprintperson

    201       Dominic lorenzo
    204       Gomez Hwang

    how do i change 1  or zero in to its actual value ?

     

     


    any idea ?
    regards
    sukavi


  • Thursday, November 05, 2009 5:13 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    change it to MAX or MIN then
    Abdallah, PMP, ITIL, MCTS
  • Thursday, November 05, 2009 5:22 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     

    Hi .

    I think there might be an issue on  MAX or MIN ,
    becasue that sql only work  on small set of data,

    for example original table that i am working on has got around "57822"  records
    so when i run the SQL it take ages to run.......and still its running without any results....

    any idea ?
    regards
    sukavi

  • Thursday, November 05, 2009 5:26 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Sukavi

    58000 records is not much. Are you sure you have proper indexes on your table?
    If you post all the query then we might be able to help you.


    Abdallah, PMP, ITIL, MCTS
    • Marked As Answer bysukavi Thursday, November 05, 2009 5:43 PM
    •  
  • Friday, November 06, 2009 2:06 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Abdshall,
    ye i do agree with you cos 58000 is not a massive amount of data,  but the problem is becasue of the data type we cant even do the Idexes...cos Varchar(Max) is not a valid indexes datatype right ?
    bellow is the original sql that i am trying to run in my DB

    DECLARE

     

    @PivotColumnHeaders VARCHAR(MAX)

    SELECT

     

    @PivotColumnHeaders =

     

    COALESCE(

    @PivotColumnHeaders

    + ',[' + cast(KeyName as varchar) + ']',

     

    '[' + cast(KeyName as varchar)+ ']'

     

    )

    FROM

     

    UserFields

     

    DECLARE

     

    @PivotTableSQL NVARCHAR(MAX)

    SET

     

    @PivotTableSQL = N'

    select

    *

    from

    (

    select

    DocID, UserField, Fieldvalue

    from Metadata_UserFields

    ) DataTable

    PIVOT

    (

    MIN(Fieldvalue)

    FOR UserField

    IN (

    '

     

    + @PivotColumnHeaders + '

    )

    ) PivotTable

    '

    EXECUTE

     

    (@PivotTableSQL)




    Actually to run that SQL it took 55 Min  ....which was not acceptable........


    i am really stuck now....dont know what to do
    thanks
    rergards
    sukavi

  • Friday, November 06, 2009 2:09 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Hi Abdshall,

    Apart from the PIVOT...is there any other way to sort this problem or PIVOT is the only way to solve my problem ?

    thanks
    regards
    sukavi
  • Friday, November 06, 2009 2:24 PMAbdshall Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Can you provide the table structure? You have two tables in your code above, UserFields and MetaData_UserFields.
    Actually PIVOT is the best way to go. There is always another way bu I'm not an expert with the SQL 2000.
    As for the indexes, you can create index on varchar columns, but not varchar(max).
    Abdallah, PMP, ITIL, MCTS
    • Edited byAbdshall Friday, November 06, 2009 2:39 PM
    •  
  • Friday, November 06, 2009 2:32 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    UserFields
    ID             = BigInt
    KeyName   =  Varchar(100)


    Metadata_UserFields

    ID          = bigint 
    DocID    = bigint
    UserField  = varchar(100) 
    FieldValue  = nvarchar(MAX) 






  • Friday, November 06, 2009 3:01 PMsukavi Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    I think becasue of the Varchar(Max) datatype its giving us problems....like take ages to run.... cos Aggregate fuctions works faster way when it comes to Decimal or int type of datatype......but in my case i keep the values as a Varchar(max)  ...for me only varchar(max) is the datatype that i can keep.

    so in this case i have to forget about the PIVOT for the movment and start looking at any other solution ? what do u think ?