Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are several different ways that you can get the result, you can use an aggregate function with a CASE expression or you can use the PIVOT function to get this. Based on your comment that any number of fields can be defined, it sounds like you will need to use dynamic SQL to get the final result. Before writing a dynamic SQL version, I would always start with a static or hard-coded version of the query, then convert it to dynamic SQL.</p> <p>Besides using these methods, I would also recommend using the windowing function <code>row_number()</code> to generate a unique value for each combination of <code>userid</code> and <code>fieldname</code>. Since you are pivoting string values, then you have to use either the <code>max</code>/<code>min</code> aggregate function which will return only one value for each fieldname, by adding the row_number you will be able to return multiple combinations of <code>Location</code>, etc for each user.</p> <p>If you were using an aggregate function with a CASE expression the query would be:</p> <pre><code>select userid, max(case when userfieldname = 'Location' then userfieldvalue end) location, max(case when userfieldname = 'Color' then userfieldvalue end) Color from ( select v.userid, f.userfieldname, v.userfieldvalue, row_number() over(partition by v.userid, v.userfieldid order by v.userfieldid) seq from userFields f left join userValues v on f.userfieldId = v.userFieldId ) d group by userid, seq order by userid; </code></pre> <p>See <a href="http://sqlfiddle.com/#!3/fa5ab/8" rel="nofollow">SQL Fiddle with Demo</a></p> <p>If you were using PIVOT, the hard-coded version of the query would be:</p> <pre><code>select userid, Location, Color from ( select v.userid, f.userfieldname, v.userfieldvalue, row_number() over(partition by v.userid, v.userfieldid order by v.userfieldid) seq from userFields f left join userValues v on f.userfieldId = v.userFieldId ) d pivot ( max(userfieldvalue) for userfieldname in (Location, Color) ) p order by userid; </code></pre> <p>See <a href="http://sqlfiddle.com/#!3/fa5ab/4" rel="nofollow">SQL Fiddle with Demo</a>.</p> <p>Once you have the correct logic you can convert the PIVOT to dynamic SQL to be executed:</p> <pre><code>DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX) select @cols = STUFF((SELECT ',' + QUOTENAME(UserFieldName) from UserFields group by UserFieldName, userfieldId order by userfieldid FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT userid, ' + @cols + ' from ( select v.userid, f.userfieldname, v.userfieldvalue, row_number() over(partition by v.userid, v.userfieldid order by v.userfieldid) seq from userFields f left join userValues v on f.userfieldId = v.userFieldId ) x pivot ( max(userfieldvalue) for userfieldname in (' + @cols + ') ) p order by userid' execute sp_executesql @query; </code></pre> <p>See <a href="http://sqlfiddle.com/#!3/fa5ab/7" rel="nofollow">SQL Fiddle with Demo</a>. All versions will give a result:</p> <pre><code>| USERID | LOCATION | COLOR | |--------|----------|--------| | 1 | Home | Orange | | 1 | Office | (null) | | 2 | Office | Red | </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload