SQL连接,具有右表

时间:2018-06-03 20:05:23

标签: sql sql-server join

对不起,如果标题不是真的可以理解,我甚至无法表达它!

为了简化,我在SQL Server 2012数据库中有两个表:一个包含请求,另一个包含与这些请求相关的操作(来自服务管理器软件)

Table REQUESTS            Table ACTIONS
+------+-------+---+      +---------+------+--------+
|Req_ID|RFC_Num|...|      |Action_ID|Req_ID|Group_ID|
+------+-------+---+      +---------+------+--------+
| 1    | I01   |...|      |  a      | 1    | 10     |
| 2    | I02   |...|      |  b      | 1    | 20     |
| 3    | I03   |...|      |  c      | 1    | 38     |
| 4    | I04   |...|      |  d      | 1    | 38     |
+------+-------+---+      |  e      | 2    | 10     |
                          |  f      | 2    | 38     |
                          |  g      | 2    | 20     |
                          |  h      | 3    | 38     |
                          |  i      | 4    | 10     |
                          +---------+------+--------+

我希望能够选择所有请求,其中该请求的最后一个操作具有group_id = 38,因此它应该返回req_id为1和3的请求,但不返回req2,因为最后一个操作是由另一个组进行的,而不是38也不涉及第38组,因为没有参与。

我尝试过像

这样的事情
select *
from REQUEST r
inner join ACTION a 
    on (
        (r.REQUEST_ID = a.REQUEST_ID) 
        and (select group_id 
            from ACTION a2 
            where a2.action_id = a.action_id
            ).GROUP_ID = 38
        )

但是我无法弄清楚如何放置" max(action_id)" (或者按照desc的顺序选择前1名)我并不真正理解如何使用像是这样的东西。

我也尝试过像这样的请求:

select *
from REQUEST r
inner join ACTION a 
    on (
        (r.REQUEST_ID = a.REQUEST_ID) 
        and (select top 1 a2.action_id, a2.group_id 
            from ACTION a2 
            where a2.action_id = a.action_id
            group by a2.ACTION_ID
            order by a2.action_id desc
            ).GROUP_ID = 38
        ) 

但是我得到了这两个错误:

  

Msg 8120,Level 16,State 1,Line 6
  列ACTION.GROUP_ID在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

     

Msg 116,Level 16,State 1,Line 11
  当EXISTS未引入子查询时,只能在选择列表中指定一个表达式。

谢谢你的帮助!

4 个答案:

答案 0 :(得分:2)

您的查询看起来比需要的时间长。试试这个:

SELECT *
FROM requests r
WHERE (
    SELECT TOP 1 Group_ID
    FROM actions
    WHERE Req_ID = r.Req_ID
    ORDER BY Action_ID DESC
) = 38

SQL Fiddle

答案 1 :(得分:0)

您的加入列错误,您正在使用:

(r.REQUEST_ID = a.ACTION_ID) 

但应该是:

(r.REQUEST_ID = a.REQUEST_ID) 

答案 2 :(得分:0)

您可以加入这些表,只保留记录Action_ID,并且此请求的其他操作不存在SELECT r.* FROM REQUESTS r INNER JOIN ACTIONS a ON a.Req_ID = r.Req_ID WHERE a.Group_ID = 38 AND NOT EXISTS (SELECT * FROM ACTIONS ai WHERE ai.Req_ID = a.Req_ID AND ai.Action_ID > a.Action_ID); 更高。

ObjectMapper objectMapper = new ObjectMapper();
Car car = new Car("yellow", "renault");
objectMapper.writeValue(new File("target/car.json"), car);

SQL Fiddle

答案 3 :(得分:0)

我倾向于使用apply

select r.*, a.*
from request r cross apply
     (select top 1 a.*
      from action a
      where a.request_id = a.request_id
      order by a.action_id desc
     )
where a.group_id = 38;

这假定“最后一次操作”基于action_id列。无论定义是什么,order by都使用。