【问题标题】:Query to return values from table B when newer than record in Table A查询以在比表 A 中的记录更新时从表 B 返回值
【发布时间】:2015-12-18 11:18:54
【问题描述】:

我有一个表格,其中包含成员的姓名、地址等,以及上次更新记录的时间戳。我有第二个表,它保存对成员记录的更新,一个保存表,直到更改得到工作人员的批准。

我有一个从成员表返回数据的查询。我现在需要检查更新表,如果更新表中的成员记录具有更新的时间戳,则返回该记录而不是成员表中的记录。

我尝试了一些方法,例如 UNIONTop 1,但不太正确。我可以做一个复杂的CASE 声明,但这样会表现良好吗?

听起来很简单,从表 A 中获取最新的记录,从表 B 中获取最新的记录,然后返回最新的一条记录。

SELECT name, address, city, state, zipcode, time_stamp
FROM Member
WHERE ID = 123

SELECT name, address, city, state, zipcode, time_stamp
FROM MemberUpdates
WHERE ID = 123

编辑:

好的,在目前的帮助下,我能够得到预期的结果。然后,我去添加额外的 where 子句,我打破了它。尝试了几种不同的方法,包括使用 CTE,但无法完全正确。这是一个有效并返回预期结果的查询,但请注意我必须传递 name_last/birth_year/memNum 两次。有没有更好的办法?

SELECT TOP 1 m.abn,
            m.aliases,
            m.birth_year,
            m.user_stamp, 

            q.updatePending,
            q.name_first,
            q.name_last,
            q.company,
            q.address1,
            q.mailing_address,
            q.city,
            q.state,
            q.zipcode,
            q.email_address

FROM (
                        SELECT  TOP 1   
                            1 AS updatePending, 
                            a.entity_number,
                            a.name_first,
                            a.name_last,
                            NULLIF(LTRIM(RTRIM(
                            LTRIM(RTRIM(ISNULL(a.company, ''))) +
                            LTRIM(RTRIM(ISNULL(a.firm_name, ''))))),'') AS company,
                            a.address1,
                            a.mailing_address,
                            a.city,
                            a.state,
                            a.zip_code AS zipcode,
                            a.internet_address AS email_address,
                            a.time_stamp
            FROM        statebar.dbo.STAGING_Address_Change_Request a
                INNER JOIN Member m ON m.entity_number = a.entity_number
            WHERE       a.entity_number = (
    SELECT m.entity_number
    FROM Member m
        INNER JOIN  Named_Entity ne ON  (ne.entity_number = m.entity_number)
    WHERE   ne.name_last = 'jones'
        AND m.birth_year = '1975'
        AND m.memNum = '12345'
        )
                AND a.time_stamp > m.time_stamp

            UNION ALL

            SELECT TOP 1 
                    0 AS updatePending,
                    ne.entity_number,
                    ne.name_first,
                    ne.name_last,
                    NULLIF(LTRIM(RTRIM(
                    LTRIM(RTRIM(ISNULL(ne.company, ''))) +
                    LTRIM(RTRIM(ISNULL(ne.firm_name, ''))))),'') AS company,
                    ne.address1,
                    ne.mailing_address,
                    ne.city,
                    ne.state,
                    ne.zip_code,
                    ne.internet_address AS email_address,
                    m.time_stamp
            FROM    Member m
                INNER JOIN  Named_Entity ne ON  (ne.entity_number = m.entity_number)
                LEFT JOIN   statebar.dbo.STAGING_Address_Change_Request a ON a.entity_number = m.entity_number
            WHERE   ne.entity_number = (
                                        SELECT m.entity_number
                                        FROM Member m
                                            INNER JOIN  Named_Entity ne ON  (ne.entity_number = m.entity_number)
                                        WHERE   ne.name_last = 'jones'
                                            AND m.birth_year = '1975'
                                            AND m.memNum = '12345'
                                            )
                AND m.time_stamp > a.time_stamp
            ORDER BY updatePending DESC, a.time_stamp DESC) q
    INNER JOIN Member m on m.entity_number = q.entity_number

ORDER BY q.time_stamp DESC 

【问题讨论】:

    标签: sql tsql select sql-server-2005


    【解决方案1】:

    这是一个简单的查询,可以帮助您返回最近的记录:

    --Only selects the top row with the most recent record
    SELECT TOP 1 * FROM record
    (
        --Select rows with the same ID
        SELECT name, address, city, state, zipcode, time_stamp
        FROM Member
        WHERE ID = 123
        UNION ALL
        SELECT name, address, city, state, zipcode, time_stamp
        FROM MemberUpdates
        WHERE ID = 123
    ) t
    ORDER BY t.time_stamp DESC --Order the table by time_stamp to get the most recent record
    -- DESC is used because datetime is ordered by oldest first in ascending order.
    

    【讨论】:

    • 这仅适用于 1 位成员。如果您有更多成员,您只会获得 1 个成员的最新记录。
    • @JodyT 我知道,但只要ID 列是唯一的并且您只想要特定成员的最新记录,那么这就足够了:)。如果我们删除 ID 条件检查,那么是的,由于TOP 1,这将只返回表上任何最近记录的 1 个结果。
    【解决方案2】:

    联合方法是个好主意,但您可能希望使用row_number() 窗口函数,而不仅仅是顶部。此外,可以使用union all 代替union。你不必关心AB 之间的重复,union all 只会表现得更好:

    SELECT name, address, city, state, zipcode, time_stamp
    FROM   (SELECT name, address, city, state, zipcode, time_stamp, 
                   ROW_NUMBER() OVER (PARTITION BY name ORDER BY time_stamp DESC) rn
            FROM   (SELECT name, address, city, state, zipcode, time_stamp
                    FROM   Member
                    UNION ALL
                    SELECT name, address, city, state, zipcode, time_stamp
                    FROM   MemberUpdates) t
            ) q
    WHERE   rn = 1
    

    【讨论】:

      【解决方案3】:

      考虑:

      SELECT
          id,
          MAX(CASE WHEN u.mx_ts IS NULL THEN m.mx_ts ELSE u.mx_ts end)
      FROM 
          (SELECT 
              id, 
              MAX(time_stamp) AS mx_ts 
          FROM 
              MEMBER 
          GROUP BY 
              id) m
          LEFT OUTER JOIN
          (SELECT 
              id, 
              MAX(time_stamp) AS mx_ts 
          FROM 
              MemberUpdates 
          GROUP BY 
              id) u ON
          m.id = u.id AND
          u.mx_ts > m.mx_ts
      GROUP BY 
          id
      

      这将加入来自memberupdates 的每个 id 的后续时间戳(如果有的话)。否则,您可以使用 member 表中每个 id 的最新时间戳。

      【讨论】:

      • 由于LEFT OUTER JOIN) u ON 之间有一个额外的“)”,您的查询看起来无法正确编译。此外,对于 CASE 语句,您没有 END。您应该重新编写查询,以便它能够正确编译并解释为什么该解决方案适用于 Connie。
      猜你喜欢
      • 2023-03-20
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      • 1970-01-01
      • 1970-01-01
      • 2013-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多