我有两种类型的物品,比方说它们是汽车和乘客。我有一张汽车桌子和一张乘客桌子。
我希望能够存储这些项目的关联,并且我正在使用另一个表格,称为“配对”。架构如下所示:
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
我需要做的是找到Passenger B的所有相关条目,所以在Pseudo 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.这是可能的,还是有更好的方法来解决这个问题?
答案 0 :(得分:3)
为什么不将Item1ID
和Item2ID
更改为carID
和passengerID
?
所以你在表格中只需要2列,并像这样添加两行?
carID, passengerID,
Car1 PassengerA
Car1 PassengerB
(将PassengerB映射到CarC和CarD):
CarC PassengerB
CarD PassengerB
答案 1 :(得分:1)
也许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
答案 2 :(得分:0)
按照面值进行设计,在此上下文中拼写OR的正确方法是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
目前尚不清楚你真的想要LEFT JOIN;我希望只使用普通(INNER)JOIN。
我不相信设计很好;根据{{3}}的建议删除项目类型。敏捷编程有许多座右铭短语,其中一个是YAGNI - 你不需要它。虽然关注未来很好,但我不确定您是否会从评论中暗示的扩展当前设计中受益。