一行中有多行

时间:2012-11-05 15:04:14

标签: sql-server tsql

我知道有类似我的问题,但不幸的是我没有找到解决问题的相应方法。

首先,这里是我的表格的简要概述:

  • Partner表:PartnerID, Name

  • Address表:PartnerID, Street, Postcode, City, ValidFrom

  • Contact表:PartnerID, TypID, TelNr, Email, ValidFrom

合作伙伴可以拥有一个或多个地址以及联系信息。通过联系信息,合作伙伴可以说2个电话号码,1个手机号码和1个电子邮件。在表中它看起来像这样:

PartnerID   TypID   TelNr                   Email               ValidFrom
1           1       0041 / 044 - 2002020                        01.01.2010
1           1       0041 / 044 - 2003030                        01.01.2011
1           2       0041 / 079 - 7003030                        01.04.2011
1           3                               myemail@hotmail.com 01.06.2011

我最终需要的是,为每个合作伙伴组合所有表格,如下所示:

PartnerID   Name    Street              Postcode        City            TelNr                               Email
1           SomeGuy MostActualStreet    MostActualPC    MostActualCity  MostActual Nr (either type 1 or 2)  MostActual Email

任何帮助?

2 个答案:

答案 0 :(得分:1)

这里有一些T-SQL得到答案,我认为你正在寻找,如果是“最实际” 你的意思是“最近的”:

WITH LatestAddress (PartnerID,Street,PostCode,City) 
AS (
    SELECT PartnerID,Street,PostCode,City
    FROM [Address] a
    WHERE ValidFrom = (
        SELECT MAX(ValidFrom) 
        FROM [Address] aMax 
        WHERE aMax.PartnerID = a.PartnerID
    )
)

SELECT p.PartnerID,p.Name,la.Street,la.PostCode,la.City
,(SELECT TOP 1 TelNr FROM Contact c WHERE c.PartnerID = p.PartnerID AND TelNr IS NOT NULL ORDER BY ValidFrom DESC) AS MostRecentTelNr
,(SELECT TOP 1 Email FROM Contact c WHERE c.PartnerID = p.PartnerID AND Email IS NOT NULL ORDER BY ValidFrom DESC) AS MostRecentEmail
FROM [Partner] p
LEFT OUTER JOIN LatestAddress la ON p.PartnerID = la.PartnerID

分解,此示例使用common table expression(CTE)获取每个合作伙伴的最新地址信息

WITH LatestAddress (PartnerID,Street,PostCode,City) 
AS (
    SELECT PartnerID,Street,PostCode,City
    FROM [Address] a
    WHERE ValidFrom = (
        SELECT MAX(ValidFrom) 
        FROM [Address] aMax 
        WHERE aMax.PartnerID = a.PartnerID
    )
)

我从合作伙伴表中加入CTE,因为我不希望没有地址的合作伙伴被排除在结果之外。

FROM [Partner] p
LEFT OUTER JOIN LatestAddress la ON p.PartnerID = la.PartnerID

在SELECT语句中,我选择了Partner表中的列,CTE,并且我编写了两个子选择,一个用于每个伙伴的最新非空电话号码,另一个用于每个用户的最新非空电子邮件地址。伙伴。我能够做到这一点作为一个子选择,因为我知道我通过选择TOP 1返回标量值。

SELECT p.PartnerID,p.Name,la.Street,la.PostCode,la.City
,(SELECT TOP 1 TelNr FROM Contact c WHERE c.PartnerID = p.PartnerID AND TelNr IS NOT NULL ORDER BY ValidFrom DESC) AS MostRecentTelNr
,(SELECT TOP 1 Email FROM Contact c WHERE c.PartnerID = p.PartnerID AND Email IS NOT NULL ORDER BY ValidFrom DESC) AS MostRecentEmail

如果您需要能够保留旧电话号码和电子邮件地址,我强烈建议您将联系人表格分成单独的电话号码和电子邮件表格,每个表格都有自己的ValidDate。

答案 1 :(得分:0)

在另一篇文章中查看我的答案,该帖子解释了如何在像您这样的案例中获取最实际的信息:Aggregate SQL Function to grab only the first from each group

PS:在你的情况下,DATE_FIELD将是ValidFrom。