【问题标题】:Table join; select 1 entry from join表连接;从加入中选择 1 个条目
【发布时间】:2012-12-04 16:35:17
【问题描述】:

在 SQL Server 中,我有两个表。一个包含所有数据的“主”表和每个条目唯一的id。另一个表是审计日志,其中来自 main 的 id 将多次存储在审计表中。

我的查询如下:

SELECT 
    a.title, a.id, a.name, t.user, t.time  
FROM 
    MainTable a      
INNER JOIN 
    AuditLog AS t ON a.id = t.id    
WHERE 
    a.NAME LIKE 'Something%'  
    AND a.ACTIVE = 'Y' 

结果如下:

TITLE           ID          NAME         USER          TIME
----------------------------------------------------------------
Something1      someth1     Some 1       User5         468534771
Something1      someth1     Some 1       User7         468574887
Something2      someth2     Some 2       User6         468584792

返回ID的多个结果。我只想要最旧的(来自AuditLog)条目,而不是每个条目。所以我想要的结果是:

TITLE           ID          NAME         USER          TIME
----------------------------------------------------------------
Something1      someth1     Some 1       User5         468534771
Something2      someth2     Some 2       User6         468584792

如何做到这一点?我正在尝试连接中的一些子查询。

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案1】:

    在sql server 2005+中,可以使用row_number()

    select title, id, name, user, time
    from
    (
      SELECT a.title, a.id, a.name, t.user, t.time,
        row_number() over(partition by a.id order by t.time) rn
      FROM MainTable a
      INNER JOIN AuditLog AS t
        ON a.id = t.id
      WHERE a.NAME LIKE 'Something%'
        AND a.ACTIVE='Y'
    ) src
    where rn = 1
    

    SQL Fiddle with Demo

    或者您可以使用子查询来获取最短时间:

    SELECT a.title, a.id, a.name, l.user, l.time
    FROM MainTable a 
    INNER JOIN AuditLog l
      ON a.id = l.id
    INNER JOIN
    (
      select min(time) Mintime, id
      from AuditLog
      group by id
    ) AS t 
      ON l.id = t.id
      AND l.time = t.mintime
    WHERE a.NAME LIKE 'Something%' 
      AND a.ACTIVE='Y';
    

    【讨论】:

    • 不需要这些子查询的恶作剧。 TOP 1 的 ORDER BY 符合要求,运行速度应该最快,具体取决于表索引等。
    • @saarp:就像用户史密斯的回答一样?还是像安多玛的那样?
    • @saarp 你读过这个问题吗? ORDER BY TOP 1 将返回一条他们不想要的记录。他们希望每个唯一 ID 都有一条记录
    【解决方案2】:
    SELECT TOP 1 a.title, a.id, a.name, t.user, t.time
    FROM MainTable a
    INNER JOIN AuditLog AS t
    ON a.id = t.id
    WHERE a.NAME LIKE 'Something%'
    AND a.ACTIVE='Y'
    ORDER BY T.DATE DESC
    

    【讨论】:

    • like 表明可能匹配多个 MainTable 记录
    【解决方案3】:

    你可以使用outer apply,比如:

    select  *
    from    MainTable a
    outer apply
            (
            select  top 1 *
            from    AuditLog t
            where   a.id = t.id
            order by
                    t.time
            ) t
    where   a.name like 'Something%'
            and a.active = 'y'
    

    【讨论】:

      【解决方案4】:

      试试这个

      SELECT a.title, a.id, a.name, t.user, t.time  
      FROM MainTable a      
          JOIN AuditLog AS t ON a.id = t.id
              JOIN (SELECT ID, MAX(TIME) AS LASTTIME FROM AUDITLOG) AS c 
              ON c.ID =  t.id AND c.LASTTIME = t.time    
      WHERE a.NAME LIKE 'Something%'  
          AND a.ACTIVE = 'Y' 
      

      【讨论】:

        猜你喜欢
        • 2019-07-11
        • 2010-12-27
        • 1970-01-01
        • 2014-08-26
        • 2014-01-01
        • 2023-04-04
        • 2011-05-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多