SELECT B1.nick, B1.date_start AS ds1, B1.date_limit AS dl1, B1.admin AS a1, B2.date_start AS ds2, B2.date_limit AS dl2, B2.admin AS a2
FROM Bans AS B1 INNER JOIN Bans AS B2
ON B1.nick=B2.nick AND B1.admin <> B2.admin AND B2.date_start BETWEEN B1.date_start AND B1.date_limit
Пользователь решил продолжить мысль 24 Мая 2010, 05:12:03:
ЗЫ: это был неправильный запрос с несколькими ошибками. Хотя в нём есть идея, как находить пересечения дат. Правильный запрос длинноват будет.
Пользователь решил продолжить мысль 24 Мая 2010, 08:36:59:
Что-то вроде (при условии, что date_start<date_limit):
SELECT T.nick, ban_start, ban_end, date_start, date_limit, admin
FROM
(SELECT T.nick, ban_start, ban_end
FROM
(SELECT T1.nick, ban_start, MIN(ban_end) AS ban_end
FROM
(SELECT nick, date_start AS ban_start
FROM Bans AS B1
WHERE NOT EXISTS
(SELECT *
FROM Bans AS B2
WHERE B2.nick=B1.nick AND B1.date_start>B2.date_start AND B1.date_start<=B2.date_limit)) AS T1
INNER JOIN
(SELECT nick, date_limit AS ban_end
FROM Bans AS B1
WHERE NOT EXISTS
(SELECT *
FROM Bans AS B2
WHERE B2.nick=B1.nick AND B1.date_limit<B2.date_limit AND B1.date_limit>=B2.date_start)) AS T2
ON T1.nick=T2.nick
WHERE ban_end>=ban_start
GROUP BY T1.nick, ban_start) AS T
INNER JOIN Bans AS B ON T.nick=B.nick AND B.date_start BETWEEN ban_start AND ban_end
GROUP BY T.nick, ban_start, ban_end, HAVING COUNT(B.nick)>1) AS T
INNER JOIN Bans AS B ON T.nick=B.nick AND B.date_start BETWEEN ban_start AND ban_end
PS: запрос не проверял, так, что могут быть различные ошибки. Думаю идея должна быть понятна - находим интервал бана (ban_start, ban_end), а потом все даты входящие в этот интервал и из них отсеиваем интервалы с одной датой