[英]How to join table in many-to-many relationship?
Here is a simplified version of my problem.这是我的问题的简化版本。 I have two tables.
我有两张桌子。 Each table has a unique ID field, but it's irrelevant in this case.
每个表都有一个唯一的 ID 字段,但在这种情况下无关紧要。
shipments
has 3 fields: shipment_id
, receive_by_datetime
, and qty
. shipments
有 3 个字段: shipment_id
、 receive_by_datetime
和qty
。
deliveries
has 4 fields: delivery_id
, shipment_id
, delivered_on_datetime
, and qty
. deliveries
有 4 个字段: delivery_id
、 shipment_id
、 delivered_on_datetime
和qty
。
In shipments
, the shipment_id
and receive_by_datetime
fields always match up.在
shipments
中, shipment_id
和receive_by_datetime
字段始终匹配。 There are many rows in the table that would appear to be duplicates based off of those two columns (but they aren't... other fields are different).根据这两列,表中有许多行似乎是重复的(但它们不是……其他字段不同)。
In deliveries
, the shipment_id
matches up to the shipments
table.在
deliveries
中, shipment_id
与shipments
表相匹配。 There are also many rows that would appear to be duplicates based off of the delivery_id
and delivered_on_datetime
fields (but they aren't again... other fields exist that I didn't list).根据
delivery_id
和delivered_on_datetime
字段,还有许多行似乎是重复的(但它们不再是......其他字段存在我没有列出)。
I am trying to pull one row per aggregate delivered_on_datetime
and receive_by_datetime
, but because of the many-to-many relationships, it's difficult.我试图为每个聚合的
delivered_on_datetime
和receive_by_datetime
拉一行,但由于多对多关系,这很困难。 Is a query somewhere along these lines correct?沿着这些路线的某处查询是否正确?
SELECT d.delivered_on_datetime, s.receive_by_datetime, SUM(d.qty) FROM deliveries d LEFT JOIN ( SELECT DISTINCT s1.shipment_id, s1.receive_by_datetime FROM shipments s1 ) s ON (s.shipment_id = d.shipment_id) GROUP BY d.delivered_on_datetime, s.receive_by_datetime
You will run into problems where the total SUM(d.qty)
will be larger than the value from SELECT SUM(qty) FROM deliveries
您将遇到总
SUM(d.qty)
大于SELECT SUM(qty) FROM deliveries
的值的问题
Something like this might be better suited for you:像这样的东西可能更适合你:
SELECT d.delivered_on_datetime, s.receive_by_datetime, SUM(d.qty) AS delivered_qty, SUM(d.qty) AS shipped_qty
FROM deliveries d
LEFT JOIN (
SELECT s1.shipment_id, s1.receive_by_datetime, SUM(s1.qty) AS qty
FROM shipments s1
GROUP BY s1.shipment_id, s1.received_by_datetime
) s ON (s.shipment_id = d.shipment_id)
GROUP BY d.delivered_on_datetime, s.receive_by_datetime
If you somehow have (or might have) a shipment_id
that has multiple values for received_by_datetime
and it's best practice to assume that something else might have corrupted the data slightly then to prevent the lines in the deliveries
table being duplicated while still returning a valid result you can use:如果您以某种方式拥有(或可能拥有)一个有多个值的
deliveries
为received_by_datetime
并且最好假设其他东西可能会稍微损坏数据,然后防止shipment_id
表中的行被重复,同时仍然返回一个有效的结果你可以使用:
SELECT d.delivered_on_datetime, s.receive_by_datetime, SUM(d.qty) AS delivered_qty, SUM(d.qty) AS shipped_qty
FROM deliveries d
LEFT JOIN (
SELECT s1.shipment_id, MAX(s1.receive_by_datetime) AS receive_by_datetime, SUM(s1.qty) AS qty
FROM shipments s1
GROUP BY s1.shipment_id
) s ON (s.shipment_id = d.shipment_id)
GROUP BY d.delivered_on_datetime, s.receive_by_datetime
Yep, the problem with many-to-many is you get the cartesian product of rows, so you end up counting the same row more than once.是的,多对多的问题是你得到了行的笛卡尔积,所以你最终会多次计算同一行。 Once for each other row it matches against.
它匹配的每一行都匹配一次。
In shipments, the shipment_id and receive_by_datetime fields always match up
在货件中,shipping_id 和 receive_by_datetime 字段始终匹配
If this means there cannot be two shipments with the same ID but different dates then your query will work.如果这意味着不能有两个货件具有相同的 ID 但不同的日期,那么您的查询将有效。 But in general it is not safe.
但总的来说,它并不安全。 ie If subselect distinct could return more than one row per shipment ID, you will be subject to the double counting issue.
即,如果 subselect distinct 可能为每个货件 ID 返回多于一行,您将面临重复计数问题。 Generically this is a very tricky problem to solve - in fact I see no way it could be with this data model.
一般来说,这是一个非常棘手的问题要解决 - 事实上,我认为这个数据 model 不可能。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.