初学SQL - 使用join

时间:2014-06-12 10:56:01

标签: sql

情景如下:

我有两张桌子:第一张有onlinespeakers列表,第二张有 他们正在讲房间。

OnlineSpeaker
------------

 - ID
 - Time
 - RoomName
 - SpeakerName

Rooms
-----
 - ID
 - Time
 - RoomName
 - Location

扬声器会定期登录OnlineSpeaker。

Rooms表用于手动添加Rooms的位置。每个RoomName 可以有多个位置,但它只是最新的(根据时间) 是有效的。

我希望从OnlineSpeaker看到每个(唯一的)RoomName和位置(如果存在) 来自Rooms。

 RoomName   Location
    ------------------------
    403     Germany
    405     France
    506     England

修改

我添加了尚未完善的查询。它确实列出了房间名称及其位置。但如果Room表中的房间有多个条目,它会提供重复的房间名称和位置。我更喜欢只为每个房间显示一个位置,并且该位置应该是Rooms表中最新添加的位置。

SELECT DISTINCT a.RoomName, b.Location
FROM OnlineSpeakers AS a LEFT OUTER JOIN
                  Rooms AS b ON a.RoomName = b.RoomName
ORDER BY a.RoomName

6 个答案:

答案 0 :(得分:3)

SELECT DISTINCT RoomName, Location
FROM OnlineSpeakers
LEFT OUTER JOIN Rooms on OnlineSpeakers.RoomName = Rooms.RoomName

答案 1 :(得分:1)

只需检查这是否符合您的要求:

with onlineSpeaker as

(select 1 id, sysdate-10 speaktime, '400' roomName, 'speak1' speakerName from dual
union
select 2 id, sysdate speaktime, '405' roomName, 'speak1' speakerName from dual
union
select 3 id, sysdate-3 speaktime, '400' roomName, 'speak4' speakerName from dual
),
Rooms as
(
select 1 room_id, sysdate-4 room_time, '400' roomMasterName, 'Germany' roomLocName from dual
union
select 2 room_id, sysdate-7 room_time, '405' roomMasterName, 'France' roomLocName from dual
union
select 3 room_id, sysdate-6 room_time, '401' roomMasterName, 'England' roomLocName from dual

)
select roomMasterName, roomLocName, speakerName  from onlineSpeaker, Rooms 
where roomMasterName = roomName
and speaktime = (select max(speaktime) from  onlineSpeaker where roomName = roomMasterName)

答案 2 :(得分:1)

写为:

with CTE as
(
    select Time,RoomName,SpeakerName , row_number() over (partition by SpeakerName order by time desc) as rownum
    from OnlineSpeaker
)
select CTE.Time,CTE.RoomName,CTE.SpeakerName , Rooms.Location
from CTE 
Join Rooms on CTE.Time = Rooms.Time and CTE.RoomName = Rooms.RoomName
and CTE.rownum = 1

点击此处Demo

答案 3 :(得分:1)

获取每间客房的最长时间,以查找最新的房间条目。外部将这些加入在线发言人。

select 
  valid_room_locations.roomname, 
  valid_room_locations.location
from onlinespeaker
left outer join
(
  select *
  from rooms
  join
  (
    select roomname, max(time) as last_time
    from rooms
    group by roomname
  ) as last_room_time on last_room_time.roomname = rooms.roomname and last_room_time.last_time = rooms.time
) as valid_room_locations 
  on valid_room_locations.roomname = onlinespeaker.roomname -- logged into that room
  --and valid_room_locations.time <= onlinespeaker.time -- provided you want only logins in this valid location
where onlinespeaker.id = 1;

我不知道您是否只想考虑登录到最新的房间位置。然后你必须比较登录时间和房间的时间#34;有效时间&#34; (注释行)。

此外,如果说话者可能登录到房间位置,注销并再次登录,那么您将获得重复。在这种情况下使用SELECT DISTINCT,就像在原始查询中一样。

答案 4 :(得分:1)

您需要做的是规范化您的数据,

OnlineSpeaker

  • 编号
  • SpeakerName

房间

  • 编号
  • ROOMNAME
  • 位置

RoomOnlineSpeaker

  • 编号
  • RoomId
  • OnlineSpeakerId
  • 时间

答案 5 :(得分:1)

SELECT DISTINCT OnlineSpeakers.RoomName, orderedRooms.Location
FROM OnlineSpeakers LEFT OUTER JOIN
    (SELECT DISTINCT RoomName, Location FROM Rooms ORDER BY Rooms.Time) 
        AS orderedRooms ON OnlineSpeakers.RoomName = orderedRooms.RoomName
GROUP BY OnlineSpeakers.RoomName
ORDER BY OnlineSpeakers.RoomName;

在加入Rooms表之前对其进行排序,并对结果进行分组。这样,在分组之前,您应该只获得具有每个RoomName最高(=最新)时间戳的结果。

最后一行是可选的,如果您的分组顺序不正确,请使用它。