Опираясь на один ответ, когда:
Да, отсутствие оператора разности множеств наносит вред.Это должно быть полностью разрешено.Однако мы можем выразить разницу между множеством с помощью дополнения и пересечения множества:
B - A = B ∩ A'
, т. Е. Различие B и A фактически является пересечением B с дополнением A.У нас есть пересечение в качестве допустимого оператора, и хотя собственное дополнение отношения является уродливым, дополнение R1 1 R относительно R (т. Е. Вещи в R, которых нет в R1), можно легко найти с помощью объединения:
SELECT DISTINCT R0.x
FROM R as R1
JOIN R as R0 ON R1.x<>R0.x
WHERE R1.x=val
- это дополнение к R, равное
SELECT DISTINCT R.x FROM R WHERE R.x=val
Итак, вот решение загадки, я думаю: все лодки зарезервированы легкодвумя или более парнями: выберите все лодки, которые находятся в таблице резервов, возьмите с собой декартово произведение результата, затем выберите каждый ряд, в котором есть разные матросы1 и матросы2.В громоздкой нотации реляционной алгебры они научили меня:
π( R.bid ) (
σ( R.bid=R2.bid and R.sid<R2.sid )( R x ρ(R, R2) )
)
(где π - оператор проекции, σ - оператор выбора, а ρ - оператор переименования)
Это объединяет idиз всех лодок, зарезервированных двумя или более людьми.Теперь я собираюсь получить все лодки, которые были зарезервированы двумя или менее парнями.Для этого я выберу все лодки, зарезервированные тремя или более парнями, и возьму дополнение набора, выбрав все строки из исходной таблицы, которых нет в этом наборе.Это не будет красиво, но здесь это так:
π(R.bid)(σ(R.bid<>R1.bid)(
π(R.bid)(R)
x
π(R1.bid) (
σ( R1.bid=R2.bid and R2.bid=R3.bid and R1.sid<R2.sid and R2.sid<R3.sid )( ρ(R, R1) x ρ(R, R2) x ρ(R, R3) )
)
))
Видите ли, я выбираю все строки, которые имеют свойство, затем выбираю все строки из исходной таблицы, которые не являются этими, сеткамы все ряды, которые не имеют собственности, здесь подразумеваются все лодки, не зарезервированные для трех или более человек, лодки, зарезервированные для двух или менее человек.
Чтобы получить лодки с двумя парнями, бронирующими ихпросто пересекайте это с набором лодок, зарезервированных более чем одним парнем.
π( R.bid ) (
σ( R.bid=R2.bid and R.sid<R2.sid )( R x ρ(R, R2) )
) ∩ π( R.bid ) (
σ(R.bid<>R1.bid)(
π(R.bid)(R)
x
π(R1.bid) (
σ( R1.bid=R2.bid and R2.bid=R3.bid and R1.sid<R2.sid and R2.sid<R3.sid )( ρ(R, R1) x ρ(R, R2) x ρ(R, R3) )
)
)
)
Тьфу.Это так ужасно, это больно.Хотелось бы, чтобы я знал более приятные обозначения.
Вкратце, это может выглядеть так, я думаю:
(SELECT DISTINCT R1.bid
FROM Reserves AS R1
JOIN Reserves AS R2 ON R1.bid = R2.bid AND R1.sid < R2.sid
) INTERSECT (
SELECT DISTINCT R.bid
FROM Reserves AS R1
JOIN Reserves AS R2 ON R1.bid = R2.bid AND R1.sid < R2.sid
JOIN Reserves AS R3 ON R1.bid = R3.bid AND R2.sid < R3.sid
JOIN Reserves AS R ON R.bid<>R1.bid
)
Обратите внимание, что это точно одно решение, если только я выразил разницу в наборе какпересечение с дополнением.