在mysql中,我在尝试获取正确的数据时遇到问题。我想我必须使用union来从两个表中获取所有结果,但不确定如何执行。
表的说明:
订购
| id | number |
|----|--------|
| 1 | 0001 |
员工
| id | name |
|----|------|
| 1 | Jon |
区域
| id | name |
|----|-------|
| 1 | ZoneA |
| 2 | ZoneB |
actual_times
| id | zone_id | eta_hours | order_id |
|----|---------|-----------|----------|
| 1 | 1 | 5 | 1 |
| 2 | 2 | 4 | 1 |
deliver_details
| id | order_id | employee_id | zone_id | hours |
|----|----------|-------------|---------|-------|
| 1 | 1 | 1 | 1 | 3 |
| 2 | 1 | 1 | 1 | 1 |
我希望得到的是区域名称,交付时间和员工交付时间的总和。如果员工没有到达该区域,则显示0
预期产量
| zone_name | hours | eta_hours | employee_name |
|-----------|-------|-----------|---------------|
| ZoneA | 4 | 5 | Jon |
| ZoneB | 0 | 4 | Jon |
我尝试在实际时间全部建立一个工会,但我做得不好。
这是我尝试过的方法(请注意,这只是为了获得带有交付时间和实际时间的正确区域)。
SELECT deliver_details.zone_id, actual_times.zone_id, zones.zone_name FROM actual_times
RIGHT JOIN deliver_details ON actual_times.order_id = deliver_details.order_id
INNER JOIN zones ON zones.id = deliver_details.zone_id
WHERE deliver_details.order_id = 1
GROUP BY deliver_details.zone_id
UNION ALL
SELECT deliver_details.zone_id, actual_times.zone_id, zones.zone_name FROM actual_times
LEFT JOIN deliver_details ON actual_times.order_id = deliver_details.order_id
INNER JOIN zones ON zones.id = actual_times.zone_id
WHERE actual_times.order_id = 1
group by actual_times.zone_id
我几乎正在尝试通过一个查询来获取所有这些信息。有办法吗?
请注意,这是我遇到的更复杂问题的简化。如果您需要更多说明或没有任何意义,请告诉我。
答案 0 :(得分:1)
无需使用UNION
。
从表employees
开始,然后与zones
和actual_times
交叉加入以获得简单的笛卡尔积。然后在deliver_details
中搜索每个员工在每个区域执行的交货;为此使用LEFT JOIN
。如果临时人员没有在给定区域上投放,请使用COALESCE
返回0
而不是NULL
。
查询:
select
z.name,
coalesce(sum(dd.hours), 0),
at.eta_hours,
e.name
from
employees e
cross join zones z
inner join actual_times at on at.zone_id = z.id
left join deliver_details dd on dd.employee_id = e.id and dd.id = at.zone_id
group by
z.name, at.eta_hours, e.name
答案 1 :(得分:1)
我想出了一个针对GMB的类似解决方案,但是使用UNION来获取0小时的行...:
SELECT z.name, sum(dd.hours), at.eta_hours, e.name
FROM zones z JOIN deliver_details dd ON z.id = dd.zone_id
JOIN actual_times at ON z.id = at.zone_id
JOIN employees e ON dd.employee_id = e.id
GROUP BY z.name, at.eta_hours, e.name
UNION
SELECT z.name, 0, at.eta_hours, e.name
FROM zones z JOIN actual_times at ON z.id = at.zone_id,
employees e
WHERE e.id NOT IN (SELECT employee_id FROM deliver_details WHERE zone_id = z.id)
答案 2 :(得分:0)
如果每个区域只有一名员工,则以下查询将为您工作:
SELECT Z.name AS zone_name
,DT.hours_total
,ACT.eta_hours_total
,E.name AS employee_name
FROM zones Z
INNER JOIN (SELECT zone_id
, SUM(eta_hours) eta_hours_total
FROM actual_times
GROUP BY zone_id) ACT ON Z.zone_id = ACT.zone_id
INNER JOIN (SELECT zone_id
, employee_id
, SUM(hours) hours_total
FROM deliver_details
GROUP BY zone_id, employee_id) DT ON Z.zone_id = DT.zone_id
INNER JOIN employees E ON DT.employee_id = E.employee_id