1

真正的问题

涉及的表及其列

accounts      [id,name]
rooms         [id,name,topic,owner]
room_admins   [account_id,room_id]

问:获取所有房间及其管理员和所有者 ID。

“所有”当然有条件(上图:WHERE name LIKE ...)管理员和所有者应该在一个名为“admins”的列中返回。我试图将它们连接成一个字符串。

我试过的

我想出了一个解决方案,但它需要使用一个无所不在的外部变量“:room_id”,它会在每个外部 SELECT 上发生变化,因此根本没有意义。

SELECT id,name,topic,
(SELECT GROUP_CONCAT(admins.account_id) AS owner
        FROM
        (SELECT account_id
        FROM `room_admins`
        WHERE room_id=:room_id
        UNION
        SELECT owner FROM `rooms` WHERE id=:room_id) admins) AS owner
FROM `rooms`
WHERE name LIKE "%htm%" OR topic LIKE "%htm%" LIMIT 20
4

2 回答 2

0

好吧,我没有对此深思熟虑......但我只是想出了这个(样本数据对进行测试很有用......所以这只是一个盲目的答案)。

select id, name, topic, group_concat(owner_admin) from (
    select id, name, topic, owner owner_admin from rooms
    union
    select id, name, topic, account_id from rooms
    left join room_admins on id = room_id
) s
where name like "%htm%" or topic like "%htm%"
group by id, name, topic

基本上我只是生成一个派生表,其中所有者和管理员混合在一列中。然后对该混合列执行分组。

于 2013-09-10T15:04:35.500 回答
0

大多数时候,当您想要选择和显示依赖数据时,您想要使用 JOIN。在这种情况下,你想和他们的管理员一起加入房间,所以基本上:

SELECT r.id, r.name, r.topic, a.id
FROM rooms r
LEFT JOIN admins a
ON r.id = a.room_id
WHERE :condition

由于您有一个不在 admins 表中的额外管理员(房间所有者),因此您必须(自己)第二次加入:

SELECT r.id, r.name, r.topic, a.id
FROM rooms r
LEFT JOIN admins a
ON r.id = a.room_id
LEFT JOIN rooms o
ON r.id = o.id
WHERE :condition

这没有给我们任何新信息,但您的问题表明您希望在单个字段中返回管理员列表。所以,最后,把它们放在一起:

SELECT r.id, r.name, r.topic, GROUP_CONCAT(a.id)
FROM rooms r
LEFT JOIN 
(
  SELECT id, room_id FROM admins
  UNION SELECT room.owner AS id, rooms.id AS room_id FROM rooms
) a
ON r.id = a.room_id
WHERE :condition
GROUP BY r.id

但是为了避免这个丑陋的子选择联合子句,我建议你把房间所有者也放到你的管理表中。

于 2013-09-10T15:08:58.113 回答