killerbunnyattack
killerbunnyattack

Reputation: 364

Modifying a view and I'm stuck

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

Answers (2)

ypercubeᵀᴹ
ypercubeᵀᴹ

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

Tomek
Tomek

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

Related Questions