【问题标题】:Get Distinct Record Based on Column. If latest value is null take old value else new value根据列获取不同的记录。如果最新值为空,则取旧值,否则取新值
【发布时间】:2015-01-07 19:53:23
【问题描述】:

我正在尝试根据 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

请告诉我我可以做到这一点

【问题讨论】:

  • 我没有看到任何会导致第二张图片的逻辑。你真的需要解释你想要什么。
  • 只是一个想法,但 PersonID 为 5 的 FirstName 字段不应该等于“NULL”,而 PersonID 为 3 的 LastName 字段不应该相同吗?
  • 请重新查看,因为我已经更新了第二张结果图片
  • @user1155773,你能粘贴实际行而不是图像
  • 那么为什么 FirstName 会是 BFG 而不是 ABC 或 CAD?

标签: sql-server sql-server-2008


【解决方案1】:

实现所需结果的一种方法是对每一列(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

【讨论】:

    【解决方案2】:

    您似乎正试图从每个列中获得“最佳”价值。 “最佳”被定义为非空值和/或最大值(即使对于 personid - 这似乎不是您的主键)。此外,在您看来,Lastname 值 34567 可能需要“ABC”而不是“ANB”。

    一种方法是对每个选择参数使用子查询。我已将您的表命名为 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
    

    【讨论】:

    • 您的查询似乎不正确。根据逻辑,它应该选择 CAD 作为第一个电话号码的名字而不是 BFG,因为 CAD 将是该组中的 Max Name。
    【解决方案3】:

    老实说,这感觉像是一团糟,但这是我能想到的最佳答案。我在下面所做的是将每一列分成一个唯一的表。然后我在表上执行分组功能,为每列查找最近的非 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,您将不会在结果集中获得第二个数字。

    【讨论】:

      猜你喜欢
      • 2020-10-09
      • 2023-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多