【问题标题】:Select entry of each group having exactly 1 entry选择每个组的条目恰好有 1 个条目
【发布时间】:2013-12-28 20:45:10
【问题描述】:

我正在寻找优化的查询

让我给你看一个小例子。 假设我有一个表,其中包含三个字段 studentId, teacherId and subject

现在我想要那些物理老师只教一个学生的数据,即

老师 300 只教学生 3 等等。

到目前为止我已经尝试过什么

select sid,tid from tabletesting with(nolock) 
where tid in (select tid from tabletesting with(nolock)
where subject='physics' group by tid having count(tid) = 1) 
and subject='physics'

上述查询运行良好。但我想要不同的解决方案,其中 我不必扫描同一张表两次。

我也尝试使用Rank() 和Row_Number(),但没有结果。

仅供参考:

我已经向您展示了一个示例,这不是我正在使用的实际表格,我的表格包含大量的行和列,并且 where 子句也非常复杂(即日期比较等),所以我不想在子查询和输出查询中给出相同的 where 子句。

【问题讨论】:

    标签: sql sql-server database sql-server-2008


    【解决方案1】:

    您可以使用窗口函数来做到这一点。假设给定教师没有重复的学生(如您的示例数据中所示):

    select tt.sid, tt.tid 
    from (select tt.*, count(*) over (partition by teacher) as scnt
          from TableTesting tt
         ) tt
    where scnt = 1;
    

    解决此问题的另一种可能更有效的方法是使用exists 子句:

    select tt.sid, tt.tid
    from TableTesting tt
    where not exists (select 1 from TableTesting tt1 where tt1.tid = tt.tid and tt1.sid <> tt.sid)
    

    【讨论】:

    • @learning 。 . .请详细说明。第二个查询是说:从老师没有其他学生的表中选择所有对。
    • 您已经编辑了答案,where 子句中的条件是tt1.sid&lt;&gt;tt.tid。
    【解决方案2】:

    另一种选择是使用解析函数:

    select sid, tid, subject from
    (
    select sid, tid, subject, count(sid) over (partition by subject, tid) cnt
    from tabletesting
    ) X 
    where cnt = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 2017-09-22
      • 2023-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多