SQL: объединение столбцов с ИЛИ - PullRequest
1 голос
/ 23 апреля 2011

У меня есть два типа предметов, допустим, это автомобили и пассажиры.У меня есть таблица для автомобилей и таблица для пассажиров.

Я хочу иметь возможность хранить ассоциации этих элементов, и для этого я использую другую таблицу, называемую «Соединения».Схема выглядит следующим образом:

Item1ID INT,
Item1Type INT,
Item2ID TEXT,
Item2Type INT,
PRIMARY KEY(Item1ID, Item2ID)

Столбцы Item1Type и Item2Type содержат значение перечисления, используемое для определения типа элемента при его поиске.Например: если я хочу связать Car1 с пассажиром A и пассажиром B, в таблице могут быть две записи:

Item1ID,       Item1Type,     Item2ID,       Item2Type 
Car1           ItemTypes.Car  PassengerA     ItemTypes.Passenger
Car1           ItemTypes.Car  PassengerB     ItemTypes.Passenger

Проблема, с которой я столкнулся, заключается в том, что я также хочу связать автомобили с пассажирами, поэтому PassengerB может бытьсвязан с автомобилем C и автомобилем D, но также и с автомобилем A. У меня уже есть запись для автомобиля A и эти две дополнительные ассоциации для сопоставления PassengerB с CarC и CarD:

Item1ID,     Item1Type,           Item2ID,   Item2Type 
PassengerB   ItemTypes.Passenger  CarC       ItemTypes.Car
PassengerB   ItemTypes.Passenger  CarD       ItemTypes.Car

Что мне нужно сделать, этонайти все связанные записи для Пассажира B, поэтому в виде псевдо SQL (с использованием SQlite) это будет:

SELECT * FROM Cars c 
          LEFT JOIN Pairings p ON 
          (c.CarID = p.Item1ID AND p.Item1Type = @CarPairingType) 
       OR (c.CarID = p.Item2ID AND p.Item2Type = @CarPairingType)

Так что мне нужно выполнить внутреннее соединение в любом поле, вроде какпереключатель, в зависимости от того, является ли тип 0 или 1. Это возможно, или есть лучший способ приблизиться к этому?

Ответы [ 3 ]

3 голосов
/ 23 апреля 2011

Почему бы вам просто не изменить Item1ID и Item2ID на carID и passengerID?

Таким образом, вам понадобится только 2 столбца в таблице и добавьте две строки следующим образом?

carID,       passengerID,
Car1           PassengerA
Car1           PassengerB

(отображение PassengerB на CarC и CarD):

CarC       PassengerB
CarD       PassengerB
1 голос
/ 23 апреля 2011

Может быть, UNION будет "будущим"?

SELECT * FROM Cars c 
INNER JOIN Pairings p ON c.CarID = p.Item1ID AND p.Item1Type = @CarPairingType
UNION
SELECT * FROM Cars c 
INNER JOIN Pairings p ON c.CarID = p.Item2ID AND p.Item2Type = @CarPairingType
0 голосов
/ 23 апреля 2011

Принимая ваш дизайн за чистую монету, правильный способ написания ИЛИ в этом контексте - UNION:

SELECT *
  FROM Cars c 
  LEFT JOIN (SELECT p1.Item1ID AS CarID
               FROM Pairings AS p1
              WHERE p1.Item1Type = @CarPairingType
              UNION
             SELECT p2.Item2ID AS CarID
               FROM Pairings AS p2
              WHERE p2.Item2Type = @CarPairingType
            ) AS p ON c.CarID = p.CarID

Не ясно, что вы на самом деле хотите левое соединение; Я ожидал бы использовать просто (ВНУТРЕННЕЕ) СОЕДИНЕНИЕ.

Я не уверен, что дизайн хороший; отбросьте типы предметов, как предложено ypercube . Agile программирование имеет ряд девизных фраз, одна из которых - YAGNI - это не нужно. Хотя хорошо следить за будущим, я не уверен, что вы выиграете от расширения существующего дизайна, как намекает в вашем комментарии.

...