【问题标题】:Modifying a view and I'm stuck修改视图,我被卡住了
【发布时间】:2012-02-05 23:39:49
【问题描述】:

我正在修改视图,但我被卡住了。

我的用户有一个旧程序查询具有父(母亲和父亲)数据的数据库视图。母亲和父亲的名字共享一个记录(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

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

【问题讨论】:

  • 对于每个user_id,是否总是有两行具有相同的user_id

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


【解决方案1】:

应该这样做:

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

【讨论】:

    【解决方案2】:

    如果每个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
    

    【讨论】:

    • 不,并非总是如此。有时只有一个。
    • @killerbunnyattack:然后,将第一个JOIN替换为LEFT JOIN
    猜你喜欢
    • 2023-02-09
    • 2016-11-06
    • 1970-01-01
    • 2022-01-04
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 1970-01-01
    相关资源
    最近更新 更多