Reputation: 364
I am working on modifying a view and I'm stuck.
My user has an old program that queries a database view that has parent (mother and father) data. The mother's and father's name shared a single record (id, fname, lname, fname2, lname2, etc...).
I built a new database and the table and corresponding view was changed to have user_id, parent_id, fname, and lname.
Parents share a user_id but have individual parent_id.
Anyway, I am trying to get results from (user_id, fname, lname) back to looking like (id, fname, lname, fname2, lname2) and got stuck. I wasn't sure where to start so I got to the following code:
This is what I start with (excluding the parent_id):
user_id fname lname expiration
4 Jane Doe 2015-01-01 00:00:00.000
4 John Doe 2015-01-01 00:00:00.000
5 Bill Smith 2015-01-01 00:00:00.000
5 Mary Smith 2015-01-01 00:00:00.000
This is the sql I am trying and got stuck with:
SELECT ROW_NUMBER() OVER ( PARTITION BY parents.user_id ORDER BY parents.user_id ASC ) RowVersion ,
dbo.parents.user_id ,
fname ,
lname ,
'' AS fname2 ,
'' AS lname2 ,
ExpirationDate AS 'expiration'
FROM dbo.parents
INNER JOIN dbo.payment ON dbo.parents.user_id = dbo.payment.User_Id
UNION
SELECT ROW_NUMBER() OVER ( PARTITION BY parents.user_id ORDER BY parents.user_id ASC ) RowVersion ,
dbo.parents.user_id ,
'' AS fname ,
'' AS lname ,
fname AS fname2 ,
lname AS lname2 ,
ExpirationDate AS 'expiration'
FROM dbo.parents
INNER JOIN dbo.payment ON dbo.parents.user_id = dbo.payment.User_Id
GROUP BY parents.user_id ,
fname ,
lname ,
ExpirationDate
This is the result of above sql;
RowVersion user_id fname lname fname2 lname2 expiration
1 4 John Doe 2015-01-01 00:00:00.000
1 4 Jane Doe 2015-01-01 00:00:00.000
2 4 Jane Doe 2015-01-01 00:00:00.000
2 4 John Doe 2015-01-01 00:00:00.000
1 5 Bill Smith 2015-01-01 00:00:00.000
1 5 Mary Smith 2015-01-01 00:00:00.000
2 5 Mary Smith 2015-01-01 00:00:00.000
2 5 Bill Smith 2015-01-01 00:00:00.000
This is what I need:
user_id fname lname fname2 lname2 expiration
4 Jane Doe John Doe 2015-01-01 00:00:00.000
5 Bill Smith Mary Smith 2015-01-01 00:00:00.000
I feel like I'm close but I also feel like I went down the wrong road. Any suggestions?
Upvotes: 0
Views: 80
Reputation: 115520
If there always exactly (or at most) two rows with same user_id
for every user_id
, then you could use this or a similar join:
parents AS a
JOIN --- or LEFT JOIN
parents AS b
ON a.user_id = b.user_id
AND a.parentsId < b.parent_id --- a field that differentiates the two rows
with the query something like:
SELECT
a.user_id ,
, a.fname AS fname,
, a.lname AS lname,
, b.fname AS fname2 ,
, b.lname AS lname2 ,
, ExpirationDate
FROM
dbo.parents AS a
LEFT JOIN
dbo.parents AS b
ON a.user_id = b.user_id
AND a.parentsId < b.parent_id
JOIN
dbo.payment AS p
ON a.user_id = p.User_Id
Upvotes: 1
Reputation: 3279
This should do:
SELECT
ROW_NUMBER() OVER (PARTITION BY A.user_id ORDER BY A.user_id ASC ) RowVersion ,
A.user_id ,
A.fname AS fname,
A.lname AS lname,
B.fname AS fname2 ,
B.lname AS lname2 ,
C.ExpirationDate AS 'expiration'
FROM
dbo.parents A
INNER JOIN dbo.parents B ON A.user_id = B.user_id AND
A.ParentId > B.ParentId -- here you have to be careful fname and lname will be randomly male or female, if you provided other fields in parents table possibly there is a way to make it deterministic
INNER JOIN dbo.payment C ON A.user_id = C.user_id
Upvotes: 4