修改视图,我卡住了

时间:2012-02-05 23:39:50

标签: sql sql-server sql-server-2005 tsql view

我正在修改视图而且我被卡住了。

我的用户有一个旧程序,用于查询具有父(母和父)数据的数据库视图。母亲和父亲的名字共享一条记录(id,fname,lname,fname2,lname2等)。

我构建了一个新数据库,并且该表和相应的视图已更改为具有user_id,parent_id,fname和lname。

父母共享一个user_id,但拥有单独的parent_id。

无论如何,我试图将(user_id,fname,lname)的结果恢复为看起来像(id,fname,lname,fname2,lname2)并且卡住了。我不知道从哪里开始,所以我得到了以下代码:

这是我的开始(不包括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

这是我正在尝试并且卡住的SQL:

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

这是上面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

这就是我需要的:

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

我觉得我很亲近,但我也觉得自己走错了路。有什么建议吗?

2 个答案:

答案 0 :(得分:4)

这应该做:

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

答案 1 :(得分:1)

如果每个user_id始终确实(或最多)两行具有相同的user_id,那么您可以使用此或类似的连接:

    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

使用类似的查询:

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