SQL:使用 OR 连接列

发布于 2024-11-03 13:22:18 字数 1179 浏览 1 评论 0原文

我有两种类型的物品,假设它们是汽车和乘客。我有一张汽车桌和一张乘客桌。

我希望能够存储这些项目的关联,为此我使用了另一个表,称为“配对”。该架构如下所示:

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 的条目和这两个额外的关联来将 PassengerB 映射到 CarC 和 CarD:

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

我需要做的是找到 Passenger 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。这可能吗,或者是否有更好的方法来解决这个问题?

I have two types of items, let's say they're Cars and Passengers. I have a table for cars, and a table for passengers.

I want to be able to store associations of these items, and I'm using another table for this, called "Pairings". The schema looks like this:

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

The Item1Type and Item2Type columns hold an enum value used to determine which type an item is when looking it up. Eg: If I want to associate Car1 with Passenger A and Passenger B, the table could have two entries:

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

The problem I have is that I also want to associate cars with passengers, so PassengerB could be associated with car C and car D, but also with car A. I already have an entry for Car A and these two extra associations to map PassengerB to CarC and CarD:

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

What I need to do is find all of the associated entries for Passenger B, so in sort of Pseudo SQL (using SQlite), this would be:

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)

So I need to do an inner join on either field, sort of like a switch, depending on whether the type is 0 or 1. Is this possible, or is there a better way to approach this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

随波逐流 2024-11-10 13:22:18

为什么不将 Item1IDItem2ID 更改为 carIDpassengerID

那么您只需要表中的 2 列并像这样添加两行?

carID,       passengerID,
Car1           PassengerA
Car1           PassengerB

(将 PassengerB 映射到 CarC 和 CarD):

CarC       PassengerB
CarD       PassengerB

Why don't you just change the Item1ID and Item2ID to carID and passengerID ?

So you will need only 2 columns in the table and add the two rows like this?

carID,       passengerID,
Car1           PassengerA
Car1           PassengerB

(mapping PassengerB to CarC and CarD):

CarC       PassengerB
CarD       PassengerB
三生一梦 2024-11-10 13:22:18

也许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

Maybe a UNION would be "future proof"?

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
一个人的夜不怕黑 2024-11-10 13:22:18

从表面上看,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;我希望只使用普通的(内部)联接。

我不相信这个设计是好的;按照 ypercube 的建议删除项目类型。敏捷编程有许多座右铭,其中之一是 YAGNI - You Ain't Gonna Need It。虽然关注未来是件好事,但我不确定您是否会从评论中暗示的扩展当前设计中受益。

Taking your design at face value, the correct way of spelling OR in this context is 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

It is not clear that you actually want a LEFT JOIN; I would expect to just use a plain (INNER) JOIN.

I'm not convinced the design is good; drop the item types as suggested by ypercube. Agile programming has a number of motto phrases, one of which is YAGNI - You Ain't Gonna Need It. While it is good to keep an eye on the future, I'm not sure that you would benefit from the extending the current design as hinted in your comment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文