Куда подзапрос должен выполнить 1 запрос для каждой возвращенной строки. Внутреннее объединение просто должно выполнить 1 запрос.
То, что вам нужно, называется мульти-диспетчеризацией .
Множественная диспетчеризация или мультиметоды - это особенность некоторых объектно-ориентированных языков программирования, в которых функция или метод могут быть динамически отправленным на основе типа времени выполнения (динамического) более чем одного из его аргументов.
Это может быть эмулировано в основных языках ООП, или вы можете использовать его напрямую, если вы используете Common Lisp.
Java Пример в статье Википедии касается даже вашей конкретной проблемы, обнаружения столкновений.
Вот подделка на наших «современных» языках:
abstract class CollisionObject {
public abstract Collision CheckForCollisionWith(CollisionObject other);
}
class Box : CollisionObject {
public override Collision CheckForCollisionWith(CollisionObject other) {
if (other is Sphere) {
return Collision.BetweenBoxSphere(this, (Sphere)other);
}
}
}
class Sphere : CollisionObject {
public override Collision CheckForCollisionWith(CollisionObject other) {
if (other is Box) {
return Collision.BetweenBoxSphere((Box)other, this);
}
}
}
class Collision {
public static Collision BetweenBoxSphere(Box b, Sphere s) { ... }
}
Вот она в Common Lisp:
(defmethod check-for-collision-with ((x box) (y sphere))
(box-sphere-collision x y))
(defmethod check-for-collision-with ((x sphere) (y box))
(box-sphere-collision y x))
(defun box-sphere-collision (box sphere)
...)
Это типичная ловушка в объектно-ориентированной разработке. Однажды я тоже пытался разрешить конфликты таким образом - но безуспешно.
Это вопрос собственности. Действительно ли класс Box владеет логикой столкновения с кругом? Почему не наоборот? Результат - дублирование кода или передача кода столкновения из круга в Box. Оба не чистые. Двойная отправка этого не решает - та же проблема с правом собственности ...
Итак, вы правы - вам нужны сторонние функции / методы, которые решают определенные коллизии, и механизм, который выбирает правильную функцию для двух сталкивающихся объектов (здесь может использоваться двойная отправка, но если количество примитивов коллизий ограничено, тогда возможно, 2D-массив функторов - более быстрое решение с меньшим количеством кода).
Вы не говорите, какой язык вы используете, поэтому я предполагаю, что это что-то вроде Java или C #.
Это ситуация, когда мультиметоды были бы идеальным решением, но большинство языков не поддерживайте их. Обычный способ имитировать их - использовать некоторые вариации шаблона посетителя - см. Любую хорошую книгу по шаблонам проектирования.
В качестве альтернативы создайте отдельный класс CollisionDetection, который проверяет столкновения между парами объектов, и если два объекта сталкиваются, он вызывает соответствующие методы для объектов, например, bomb.explode () и player.die (). Класс может иметь большую справочную таблицу с каждым типом объекта по строкам и столбцам, а также записи, дающие методы для вызова обоих объектов.
Возможно, у вас есть объект столкновения, который содержит методы для тестирования различных типов столкновений. Методы могут возвращать другие объекты, содержащие точку столкновения и другую необходимую информацию.
Вы должны использовать checkForCollisionWith: aCollisionObject, и поскольку все ваши объекты расширяют CollisionObject, вы можете поместить туда всю общую логику.
В качестве альтернативы вы можете использовать шаблон проектирования делегирования для разделения общей логики между разными классами.
Первый вариант: Сделать столкновение направленным. Например, если ящик неподвижен, он не проверяет свои столкновения ни с чем другим; но движущийся круг проверяет столкновение с коробкой (и другими неподвижными объектами). Это нелогично, потому что всю жизнь нас учат «равным и противоположным реакциям». Ловушка: движущиеся объекты будут дублировать столкновения с другими движущимися объектами.
Второй вариант: Дайте каждому объекту уникальный идентификационный номер. В методе проверки коллизий проверяйте коллизию только в том случае, если первый параметр / объект имеет более низкий идентификатор, чем второй параметр.
Скажем, поле имеет идентификатор = 2, а круг имеет идентификатор = 5. Тогда будет выполняться «блок сталкивается с кругом», поскольку box.id