none
一个SQL语句中IN的理解,谢谢 RRS feed

  • 问题

  • -- 操作日志表的所有记录
    
    
    
    SELECT JobLogId,FunctionId,OperateTime 
    FROM JobLog
    
    
    查询结果:
    
    
    
    1 001 2007-11-01
    
    
    
    2 001 2007-11-02
    
    
    
    3 001 2007-11-03
    
    
    
    4 002 2007-11-04
    
    
    
    5 002 2007-11-05
    
    
    
    6 003 2007-11-06
    
    
    
    7 004 2007-11-07
    
    
    
    8 004 2007-11-08
    
    
    
    9 005 2007-11-09
    
    
    
    10 005 2007-11-10
    
    
    
    
    
    
    
    -- 每个功能最后一次操作记录
    
    
    
    SELECT * FROM JobLog A
    
    
    
    WHERE JobLogId in
    
    
    
     (SELECT TOP 1 JobLogId FROM JobLog 
    
    
    
      WHERE A.FunctionId = FunctionId ORDER BY OperateTime DESC
    
    
    
     )
    
    
    
    

    查询结果: 3 001 2007-11-03

                     5 002 2007-11-05

                     6 003 2007-11-06

                     8 004 2007-11-08

                     10 005 2007-11-10

     这个查询语句怎样理解??谢谢

     

    2010年9月19日 14:51

全部回复

  • 举个例子, 当你主语取第一条记录"1 001 2007-11-01"时,你子句取出的是"3 001 2007-11-03", 不匹配放弃,一直到你主句取到"3 001 2007-11-03" 与子句匹配后返回.
    同理,第二条子句取出的是"5 002 2007-11-05", 返回的是"5 002 2007-11-05",

    同理有

    6 003 2007-11-06

                     8 004 2007-11-08

                     10 005 2007-11-10

    2010年9月20日 9:10
  • 这个查询语句也可以实现相同功能,即每个功能最后一次操作记录.

    WITH tempt AS
    (
      SELECT *,
        ROW_NUMBER() OVER(PARTITION BY [FunctionId] ORDER BY [OperateTime] desc) AS rn
      FROM [testDB].[dbo].[JobLog]
    )
    select * FROM tempt WHERE rn = 1; 


    Mark as Answer if it helps. This posting is provided "AS IS" with no warranties, confers no rights.
    2010年9月21日 8:46
  • 不太理解你说的意思,不过还是谢谢,继续等待ING
    2010年9月25日 6:31
  • 这个查询可以理解如下

    先是这句会遍历整个表

    SELECT *
    FROM  JobLog A
    

     

    然后在整表遍历的时候,子查询

     

    SELECT TOP 1
        JobLogId
    FROM   JobLog
    WHERE   A.FunctionId = FunctionId
    ORDER BY OperateTime DESC 
    

     

    会根据前面遍历的时候的每一次的FunctionID,找出相同FunctionID中时间最近的一次的JobLogId

    你可以想象成前三条数据遍历的时候,子查询得到的都是3,第4,5条数据遍历的时候,子查询得到的是5....

     

    最后,将主查询(整表遍历)得到的结果进行一次过滤

    WHERE  JobLogId IN ( 3 ,3 ,3 , 5 ,5 ,6 ,8 ,8 ,10 ,10)
    

    就得到了你要的结果。

    当然,这只是一个思考的路线,实际SQL会在这个过程中做很多优化。

    具体一段SQL怎么处理其实是可以通过Sql Server Management Studio看出来的,就是用SSMS的“查询(Query)”菜单中“显示评估执行计划(Display Estimated Execution plan)”,或按Ctrl+L来查看。 执行计划图按从上往下,从右往左的顺序理解,点击具体的过程可以看到他执行的SQL部分。


    Love Your Neighbor as Yourself
    2010年9月26日 3:38
  • 当成游标理解就可以了

    循环处理 JobLog 的每条记录

    对于每条记录(假设为A记录), 做如下处理:

    1. 判断子查询所查到的 JobLogId 是否与当前这条记录的 JobLogId 相同, 子查询中, 引用到的 A 的字段值为A记录对应的值

    2. 如果子查询查询的值与A记录的JobLogId值相同, 则返回A记录, 否则不返回任何值

     

    2010年9月26日 4:28
  • 我的语句的意思就像是下面这个语句,但这个语句是不能通过语法检查的:

    SELECT TOP 1 JobLogId FROM JobLog group by JobLogId order by JobLogId

    但上面的语句是可以执行并返回正确结果的.


    Mark as Answer if it helps. This posting is provided "AS IS" with no warranties, confers no rights.
    2010年10月15日 22:01
  • 似乎问题被复杂化了, 似乎你应该举例描述你的需求, 然后讨论如何实现就好了.

    另外, 这个语句是能通过语法检查的, 如果不能, 则描述你的版本

    SELECT TOP 1 JobLogId FROM JobLog group by JobLogId order by JobLogId

    2010年10月18日 4:33