【问题标题】:Historical sql Table With Bits Of User Information - Make New Table With 1 Entry & All Information具有用户信息位的历史 sql 表 - 使用 1 个条目和所有信息创建新表
【发布时间】:2017-01-17 18:13:17
【问题描述】:

我有一个表(客户),其中包含 43 列用户信息(名字、姓氏、地址、城市、州、邮编、电话、电子邮件、visitDate、lastActive 等...)

每天晚上,我都会从我们的客户那里收到当天拜访他们的客户的信息。这些访问存储到客户表中,而不会删除旧记录。旧记录标记为 lastActive = 0,新记录标记为 lastActive = 1。任何空字段都存储为“未知”。

显然,这会导致一个非常大的表需要一段时间来查询。因此,我计划制作一个仅包含不同用户及其最完整信息的新表。

例如:如果 Bob Smith 在 1 月 1 日导入时没有电话或电子邮件,然后他在 8 月 1 日再次导入时使用电话但没有电子邮件,然后在 9 月 1 日再次导入时没有电话但电子邮件,我的客户表看起来像这样:

CustImportID  CustomerKey  FirstName  LastName  Phone      Email   visitDate   lastActive
1             1            Bob        Smith     Unknown    Unknown 2016-01-01  0
2             1            Bob        Smith     5551231234 Unknown 2016-08-01  0
3             1            Bob        Smith     Unknown    1@2.io  2016-09-01  1

所以我的问题是,从客户表中获取不同人员并将他们插入到新表中的最佳方法是什么,鲍勃只是一个条目,但我会对每个字段都有值(如果每个条目有电话,例如,我们会从最近的条目中提取电话),结果是这样的:

CustomerKey  FirstName  LastName  Phone      Email  visitDate   
1            Bob        Smith     5551231234 1@2.io 2016-09-01

【问题讨论】:

  • 我什至能想到的唯一方法是创建一个包含 43 个子查询的查询——这显然不是最好的方法。我知道肯定有更好的方法,但我想不出一个。

标签: sql sql-server tsql merge greatest-n-per-group


【解决方案1】:

您可以使用FIRST_VALUE 来忽略'Uknown' 值:

SELECT FirstName, LastName,
       FIRST_VALUE(Phone) OVER (ORDER BY CASE 
                                            WHEN Phone='Unknown' THEN 1 
                                            ELSE 0
                                         END,
                                         visitDate DESC) AS Phone,
       FIRST_VALUE(Email) OVER (ORDER BY CASE 
                                            WHEN Email='Unknown' THEN 1 
                                            ELSE 0
                                         END,
                                         visitDate DESC) AS Email
FROM mytable

FIRST_VALUE 可从 SQL Server 2012 获得。它选择由 OVER 子句的 ORDER BY 指定的最新字段值。由于ORDER BY 子句中的CASE'Unknown' 值的优先级最低。

【讨论】:

    【解决方案2】:

    您可以使用所有记录中的最大值,这将导致:

    select customerkey, max(firstname), max(lastname), max(phone), max(email), max(visitdate) from yourtablename
    

    如果您有两个更有效的条目,则使用 row_number 并根据最近的值选择其中的最大值

    【讨论】:

    • 我曾考虑过行号,但后来我必须在每个字段上做一个行号。
    猜你喜欢
    • 1970-01-01
    • 2017-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多