联接

时间:2016-05-02 14:23:57

标签: sql tsql join subquery max

我正在尝试检索与名称关联的最新地址(因为每个名称通常有多个地址)。我在连接中使用子查询创建了以下查询。我可以按照自己的意愿撤回每个聚会的一个地址,但地址/城市并不总是匹配,或者返回的地址不是最近的地址(按照相关日期)。我用MAX写错了子查询吗?有没有办法确保正确的城市与正确的地址一致?

select 
    [demographics].[DOB],
    Address1,
    Address2,
    City,
    State,
    Zip

from [demographics]
    left join (select
                    [address].[demographic_ID], 
                    max([address].[address1]) as Address1,
                    max([address].[address2]) as Address2,
                    max([address].[city]) as City,
                    max([states].[state_title]) as 'State',
                    max([dbo].[address].[zip]) as Zip
                from [address]
                    inner join [states] on [address].[state_ID] = [states].[state_ID]
                group by [address].[demographic_ID]) as AddressSub 
        on [demographics].[demographic_ID] = AddressSub.[demographic_ID];

4 个答案:

答案 0 :(得分:0)

为了做到这一点,我需要知道地址表的PK以及你如何确定"最近的"

SELECT
    [demographics].[DOB],
    Address1,
    Address2,
    City,
    State,
    Zip

FROM [demographics]
LEFT JOIN (SELECT
           Row_number() over (partition by Demographic_ID ORDER BY Demographic_ID Desc) RN
           [address].[demographic_ID], 
           [address].[address1] as Address1,
           [address].[address2] as Address2,
           [address].[city] as City,
           [states].[state_title] as 'State',
           [address].[zip] as Zip
           FROM [address]
           INNER JOIN [states] 
              on [address].[state_ID] = [states].[state_ID]
           GROUP BY [address].[demographic_ID]) as AddressSub 
  on [demographics].[demographic_ID] = AddressSub.[demographic_ID]
 and  AddressSub.RN = 1

答案 1 :(得分:0)

最新的将是地址栏中的最后一个条目

select 
[demographics].[DOB],
Address1,
Address2,
City,
State,
Zip

from [demographics]
left join (select top 1 max([address.EntryDate)
                [address].[demographic_ID], 
                [address].[address1] as Address1,
                [address].[address2] as Address2,
                [address].[city] as City,
                [states].[state_title] as 'State',
                [dbo].[address].[zip] as Zip
            from [address]
                inner join [states] on [address].[state_ID] = [states].[state_ID]
            group by [address].[demographic_ID], 
                [address].[address1] as Address1,
                [address].[address2] as Address2,
                [address].[city] as City,
                [states].[state_title] as 'State',
                [dbo].[address].[zip] as Zip

    on [demographics].[demographic_ID] = AddressSub.[demographic_ID];

答案 2 :(得分:0)

如果查看子查询,您实际要求的是每列的最大值(因为这些是按字母顺序最大的字符串)字段。这不太可能从同一地址行返回字段。例如,如果您有两行都与相同的demographic_ID相关,其中address_1 = Z且address_2 = A,另一行则address_1 = A且address_2 = Z,则会返回Z和Z(来自第一个的address_1和来自的第一个地址_2)第二)。我不认为这是你的目标。

首先,如果您有这个选项,可以通过稍微更改数据库来使事情变得更容易一些。您可以在人口统计信息中添加最新的地址ID,您可以更新并使用该ID直接链接到您想要的地址。或者,您可以在地址中添加一列,用于存储创建的时间或编辑的时间,并使用此列来获取最近的时间。

或者,如果您不想更改数据库,可以按照上面的建议进行操作,并使用rownumber作为地址中最新项目的标识符。您首先需要在子查询中返回demographic_id和maximum(rownumber),然后在第二个子查询中返回地址的其余详细信息。

答案 3 :(得分:0)

在SQL Server中解决此问题的一种方法是使用outer apply(在其他数据库中,这称为“横向连接”)。假设您有一些确定最新地址的方法,您可以这样做:

select d.*, a.*
from [demographics] d outer apply
     (select a.*, s.state_title as state
      from address a inner join
           states s
           on a.[state_ID] = s.[state_ID]
      where a.demographic_ID = d.demographic_ID
      order by ?? desc
     ) a;

(我忽略了具体专栏的细节。)

??表示定义“最新”的列 - 例如,标识主键或记录创建日期。在这种情况下,outer apply基本上是一个相关子查询,允许您返回多个列。

注意:我强烈建议使用表别名。它们使查询更容易编写和阅读。