1

I have two tables Users and UserAttributes in SQL DB.

Table have structure like

enter image description here

Out required is

enter image description here

My attempted query

Select * from (
Select u.UserId,u.Username,u.UserEmail,ua.objectName,ua.objectValue 
from Users u join userAttribute on u.UserId=ua.UserId
where ua.objectName='city' or pv.objectName='phone')) results
PIVOT (count(UserId)
For objectName IN ([city],[phone])) As pivot_table;

Current output

enter image description here

Still it is an double entry also for the reason I am not aware the city and phone results are in 0 and 1 (boolean).

Please help getting the desired output.

4
  • 3
    There is no phone available for userId : 1, so how can you desire the phone to come in output. Commented Jan 28, 2020 at 11:41
  • from User will never work. USER is a reserved keyword in SQL Server. Are you actually using T-SQL? Images of data, also, really don't help us help you. This looks like you have denormalised data though. city and phone should be 2 separate columns in your data, not 1. Or is this process so that you can fix your design? (I hope so). Commented Jan 28, 2020 at 11:41
  • @ShubhamNagota and Larnu sorry was in hurry I have edited it. Larnu this approach allows to add any objName attributes in future not just city and phone. Commented Jan 28, 2020 at 11:52
  • If you have any number of attributes, the only way to pivot is to use dynamic SQL. Take a look at this question: stackoverflow.com/questions/10404348/… Commented Jan 28, 2020 at 12:01

5 Answers 5

1

You can do aggregation :

select u.UserId, u.username, u.usermemail,
       max(case when ua.objectname = 'city' then objvalue end),
       max(case when ua.objectname = 'phone' then objvalue end)
from User u join 
     userAttribute ua
     on u.UserId = ua.UserId
group by u.UserId, u.username, u.usermemail;
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @yogesh your solution is also correct but as Gordon answered first I have accepted it.
1

You can use conditional aggregation to extract the values from the UserAttributes table:

SELECT u.userid, u.userName, u.userEmail,
       MAX(CASE WHEN ua.objName = 'city'  THEN ua.objValue END) AS city,
       MAX(CASE WHEN ua.objName = 'phone' THEN ua.objValue END) AS phone,
FROM Users u
JOIN UserAttributes ua ON ua.userid = u.userid
GROUP BY u.userid, u.userName, u.userEmail

Comments

0

To pivot just two columns, joins is convenient:

select u.*, uac.objvalue as city, uap.objvalue as phone
from users u left join
     userattributes uac
     on uac.userid = u.userid and
        uac.objname = 'city' left join
     userattributes uap
     on uap.userid = u.userid and
        uap.objname = 'phone';

If you want only rows with matches, then add:

where uac.objvalue is not null or uap.objvalue is not null

If you have more columns, then join and group by is probably a better approach:

select u.*, au.*
from users u join
     (select ua.userid,
             max(case when objname = 'city' then objvalue end) as city,
             max(case when objname = 'phone' then objvalue end) as phone
      from userattributes ua
      group by ua.userid
     ) ua
     on u.userid = ua.userid;

1 Comment

Thanks @Gordan as you said I have used "join and group by" approach to get required results.
0

Please try following query. Hope this will help

DECLARE @Users table(userid int, username varchar(50))
insert into @Users  select 1,'Shiv'
insert into @Users  select 2,'Ajay'

DECLARE @UserAttr table(userid int,objname varchar(100),objvalue varchar(100))
insert into @UserAttr select 1,'City','Chd'
insert into @UserAttr select 1,'phone','9646XXXX'
insert into @UserAttr select 2,'phone','8985XXXX'


select * FROM
(
select u.userid,u.username,ua.objname,ua.objvalue FROM @Users u
join  @UserAttr ua on u.userid = ua.userid
)a pivot (min(a.objvalue) FOR a.objname in ([city],[phone]))p

1 Comment

not able to get the required result with this query.
0

Below is the query which you can try with or without pivot.

1. Without Pivot:- 

SELECT  ur.UserId,ur.UserName,ur.UserEmail,
        Max(CASE WHEN ua.objName = 'city' THEN ua.ObjValue END) as city,
       Max (CASE WHEN ua.ObjName = 'phone' THEN ua.ObjValue END) as Phone
FROM    Users ur 
        JOIN UserAttribute ua ON ur.UserId = ua.UserId

GROUP BY ur.UserId,ur.UserName,ur.UserEmail

2. With Pivot :- 

select * from (select us.UserId,us.UserName,us.UserEmail,ua.ObjName,ua.ObjValue from users us inner join UserAttribute ua on us.UserId=ua.UserId)t pivot
(
max(ObjValue)
For ObjName in ([city],[phone]) 

) as pivot_table;


Please try this query and let me know the results.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.