根据专栏获得独特的记录。如果最新值为null,则使用旧值,否则为新值

时间:2015-01-07 19:53:24

标签: sql-server sql-server-2008

我正在尝试根据PrimaryMobile选择每个组的最大值。我的想法是,对于每个组,我想选择其最近输入的值(基于其personID而不是DateCreated)

我的数据看起来像

PersonID    PrimaryMobile    FirstName    LastName    City    DateCreated
1           34455666         CAD          Null        Pu      01-01-2014
2           34455666         ABC          AND         Null    02-01-2015
3           34455666         BFG          Null        Tu      Null
4           34567            New          ABC         Null    01-01-2014
5           34567            Null         Null        Ta      02-01-2014

我想要的结果

PersonID    PrimaryMobile    FirstName    LastName    City    DateCreated
3           34455666         BFG          AND         Tu      02-01-2015
5           34567            New          ABC         Ta      02-01-2014

请让我知道我能做到这一点

3 个答案:

答案 0 :(得分:2)

您可以通过每个列的子选择(PrimaryMobile除外)实现所需结果的一种方式:

SELECT 
(SELECT TOP 1 PersonId FROM MyTable t2 WHERE t2.PrimaryMobile=t1.PrimaryMobile ORDER BY PersonID DESC) AS PersonID,
t1.PrimaryMobile,
(SELECT TOP 1 FirstName FROM MyTable t2 WHERE t2.PrimaryMobile=t1.PrimaryMobile AND t2.FirstName IS NOT NULL ORDER BY PersonID DESC) AS FirstName
{Same as above replacing "FirstName" with "LastName" and "City"}
FROM MyTable t1
GROUP BY t1.PrimaryMobile

答案 1 :(得分:0)

您似乎正在努力获得最好的"每列的价值。 "最佳"被定义为非空和/或最大值(即使对于personid - 它似乎不是你的主键)。此外,您似乎可能需要" ABC"而不是" ANB"对于Lastname值34567。

执行此操作的一种方法是使用每个选择参数的子查询。我已将您的表格命名为t1:

SELECT DISTINCT t1_outer.PrimaryMobile,
  (SELECT MAX(PersonId) FROM t1 t1_inner WHERE t1_inner.PrimaryMobile = t1_outer.PrimaryMobile Where PersonId IS NOT NULL GROUP BY t1_inner.PrimaryMobile) AS PersonID,
  (SELECT MAX(FirstName) FROM t1 t1_inner WHERE t1_inner.PrimaryMobile = t1_outer.PrimaryMobile  WHERE FirstName IS NOT NULL GROUP BY t1_inner.PrimaryMobile) AS FirstName,
  (SELECT MAX(LastName) FROM t1 t1_inner WHERE t1_inner.PrimaryMobile = t1_outer.PrimaryMobile WHERE LastName IS NOT NULL GROUP BY t1_inner.PrimaryMobile) AS LastName,
(SELECT MAX(City) FROM t1 t1_inner WHERE t1_inner.PrimaryMobile = t1_outer.PrimaryMobile WHERE City IS NOT NULL GROUP BY t1_inner.PrimaryMobile) AS City,
(SELECT MAX(DateCreated) FROM t1 t1_inner WHERE t1_inner.PrimaryMobile = t1_outer.PrimaryMobile WHERE DateCreated IS NOT NULL GROUP BY t1_inner.PrimaryMobile) AS DateCreated
FROM t1 t1_outer

答案 2 :(得分:0)

这老实说感觉就像一团糟,但这是我能想到的最佳答案。我在下面做的是将每列分成一个唯一的表。然后,我在表上执行分组功能,查找每列的最新Non Null值,并根据PrimaryMobile重新加入列。另外作为一个注释,因为你没有给出表名,我将假设表名为" Person"

<强> SQL

Select Max(Person.PersonID),
    Person.PrimaryMobile,
    FNameSet.FirstName,
    LNameSet.LastName,
    CitySet.City,
    DateSet.DateCreated
From Person
    Left Outer Join (Select FNamePerson.PersonID, 
                            FNamePerson.PrimaryMobile, 
                            FNamePerson.FirstName,
                            FNameRowID = ROW_NUMBER() OVER (PARTITION BY FNamePerson.PrimaryMobile ORDER BY FNamePerson.PersonID DESC)
                     From Person FNamePerson
                     Where FNamePerson.FirstName Is Not Null) FNameSet
        On Person.PrimaryMobile = FNameSet.PrimaryMobile
    Left Outer Join (Select LNamePerson.PersonID, 
                            LNamePerson.PrimaryMobile, 
                            LNamePerson.LastName,
                            LNameRowID = ROW_NUMBER() OVER (PARTITION BY LNamePerson.PrimaryMobile ORDER BY LNamePerson.PersonID DESC)
                     From Person LNamePerson
                     Where LNamePerson.LastName Is Not Null) LNameSet
        On Person.PrimaryMobile = LNameSet.PrimaryMobile
    Left Outer Join (Select CityPerson.PersonID, 
                            CityPerson.PrimaryMobile, 
                            CityPerson.City,
                            CityRowID = ROW_NUMBER() OVER (PARTITION BY CityPerson.PrimaryMobile ORDER BY CityPerson.PersonID DESC)
                     From Person CityPerson
                     Where CityPerson.City Is Not Null) CitySet
        On Person.PrimaryMobile = CitySet.PrimaryMobile
    Left Outer Join (Select DatePerson.PersonID, 
                            DatePerson.PrimaryMobile, 
                            DatePerson.DateCreated,
                            DateRowID = ROW_NUMBER() OVER (PARTITION BY DatePerson.PrimaryMobile ORDER BY DatePerson.PersonID DESC)
                     From Person DatePerson
                     Where DatePerson.DateCreated Is Not Null) DateSet
        On Person.PrimaryMobile = DateSet.PrimaryMobile
 Where FNameRowID = 1
   And LNameRowID = 1
   And CityRowID = 1
   And DateRowID = 1
Group By Person.PrimaryMobile,
         FNameSet.FirstName,
         LNameSet.LastName,
         CitySet.City,
         DateSet.DateCreated

请注意,如果任何一个列没有与其组关联的值,此解决方案将删除一个数字。即如果您从数据集的FirstName列中删除了NEW,则不会在结果集中获得第二个数字。