英文:
How can I create a 0 value when joining two different tables?
问题
I have two tables, one for planned hours in production and another one for actual hours measured in production.
Table PlannedHours for Order = 'abc123' looks like this:
| Operation | Order | Planned_hrs |
| ---------- | ------ | ----------- |
| Activity 1 | abc123 | 1 |
| Activity 2 | abc123 | 2 |
Table ActualHours for Order = 'abc123' can look like this:
| Operation | Order | Actual_hrs |
| ---------- | ------ | ----------- |
| Activity 1 | abc123 | 1,75 |
| Activity 2 | abc123 | 2,2 |
Then I would like to join and get this table:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 1 | abc123 | 1 | 1,75 |
| Activity 2 | abc123 | 2 | 2,2 |
However, in this particular example Table ActualHours for Order = 'abc123' looks like this:
| Operation | Order | Actual_hrs |
| ---------- | ------ | ----------- |
| Activity 2 | abc123 | 2,2 |
because Activity 1 was conducted elsewhere and therefore not measured.
I would like to join the tables and get this result:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 1 | abc123 | 1 | 0 |
| Activity 2 | abc123 | 2 | 2,2 |
I have tried this code:
SELECT
b.[Operation],
b.[Order],
COALESCE(e.[Planned_hrs], 0) as Planned_hrs,
COALESCE(b.[Actual_hrs], 0) as Actual_hrs
FROM Actual_hours b
LEFT JOIN Planned_hours e
ON b.[Order] = e.[Order] AND b.[Operation] = e.[Operation]
WHERE b.[Order] = 'abc123'
ORDER BY b.[Order] ASC;
This query should give you the desired result by using the COALESCE function to handle cases where there's no matching record in the Planned_hours table. It replaces NULL values with 0 for Planned_hrs and Actual_hrs.
英文:
I have two tables, one for planned hours in production and another one for actual hours measured in production.
Table PlannedHours for Order = 'abc123' looks like this:
| Operation | Order | Planned_hrs |
| ---------- | ------ | ----------- |
| Activity 1 | abc123 | 1 |
| Activity 2 | abc123 | 2 |
Table ActualHours for Order = 'abc123' can look like this:
| Operation | Order | Actual_hrs |
| ---------- | ------ | ----------- |
| Activity 1 | abc123 | 1,75 |
| Activity 2 | abc123 | 2,2 |
Then I would like to join and get this table:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 1 | abc123 | 1 | 1,75 |
| Activity 2 | abc123 | 2 | 2,2 |
However, in this particular example Table ActualHours for Order = 'abc123' looks like this:
| Operation | Order | Actual_hrs |
| ---------- | ------ | ----------- |
| Activity 2 | abc123 | 2,2 |
because Activity 1 was conducted elsewhere and therefore not measured.
I would like to join the tables and get this result:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 1 | abc123 | 1 | 0 |
| Activity 2 | abc123 | 2 | 2,2 |
I have tried this code:
SELECT
b.[Operation]
b.[Order]
b.[Actual_hrs]
e.[Planned_hrs]
from Actual_hours b
left join Planned_hours e
on b.[Order] = e.[Order]
where b.[Order] = 'abc123'
group by b.[Order], b.[Operation], e.[Planned_hrs]
order by b.[Order] asc
but then I get the following result:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 1 | abc123 | 1 | 1,75 |
| Activity 2 | abc123 | 2 | 1,75 |
so I tried adding a condition on the join:
SELECT
b.[Operation]
b.[Order]
b.[Actual_hrs]
e.[Planned_hrs]
from Actual_hours b
left join Planned_hours e
on b.[Order] = e.[Order] and b.[Operation] = e.[Operation]
where b.[Order] = 'abc123'
group by b.[Order], b.[Operation], e.[Planned_hrs]
order by b.[Order] asc
Which partially works because I get the following result:
| Operation | Order | Planned_hrs | Actual_hrs |
| ---------- | ------ | ----------- | ---------- |
| Activity 2 | abc123 | 2 | 1,75 |
but, unfortunately, then I am missing Activity 1.
答案1
得分: 1
你正在执行From Actual_hours LEFT JOIN Planned_hours
。这意味着对于Actual_hours的每一行,如果存在的话,你会得到Planned_hours的行。
我认为在你的情况下,你想要完全相反的情况,就像这样:
SELECT
e.[Operation],
e.[Order],
e.[Planned_hrs],
ISNULL(b.[Actual_hrs], 0)
from Planned_hours e
left join Actual_hours b
on b.[Order] = e.[Order] and b.[Operation] = e.[Operation]
where e.[Order] = 'abc123'
order by e.[Order] asc
英文:
You are doing From Actual_hours LEFT JOIN Planned_hours
.
That means for each row of Actual_hours you get lines of Planned_hours if exists.
I think in your case you want the exact opposit like that :
SELECT
e.[Operation],
e.[Order],
e.[Planned_hrs],
ISNULL(b.[Actual_hrs], 0)
from Planned_hours e
left join Actual_hours b
on b.[Order] = e.[Order] and b.[Operation] = e.[Operation]
where e.[Order] = 'abc123'
order by e.[Order] asc
答案2
得分: 0
我正在使用 SQL Fiddler。以下是我用来重现和解决你的问题的步骤:
创建表格。
create table planned
(
Operation1 varchar(32),
Order1 varchar(32),
Planned_hrs varchar(32)
);
create table actual
(
Operation1 varchar(32),
Order1 varchar(32),
Actual_hrs varchar(32)
);
添加数据。
-- 添加数据
insert into planned values ('Activity 1', 'abc123', '1');
insert into planned values ('Activity 2', 'abc123', '2');
-- insert into actual values ('Activity 1', 'abc123', '1,75');
insert into actual values ('Activity 2', 'abc123', '2,2');
由于我们没有测量第3行,它没有出现在表中。另一方面,如果你有数据但想要以不同方式处理它,可以添加一个名为"off-site"的列。
选择数据。
select p.*, isnull(a.actual_hrs, 0) as hours
from planned as p
left join actual as a
on p.Operation1 = a.Operation1 and
p.Order1 = a.Order1
这种技术是左连接,使用了字段上的 isnull() 函数来处理缺失数据,这将得到零值。
SQL Fiddler的屏幕截图:
输出的屏幕截图:
英文:
I am using sql fiddler. Here are the steps that I used to reproduce and solve your problem.
Create the tables.
create table planned
(
Operation1 varchar(32),
Order1 varchar(32),
Planned_hrs varchar(32)
);
create table actual
(
Operation1 varchar(32),
Order1 varchar(32),
Actual_hrs varchar(32)
);
Add the data.
-- Add data
insert into planned values ('Activity 1', 'abc123', '1');
insert into planned values ('Activity 2', 'abc123', '2');
-- insert into actual values ('Activity 1', 'abc123', '1,75');
insert into actual values ('Activity 2', 'abc123', '2,2');
Since we did not measure line 3, it did not make it into the table. On the other hand, if you have the data but want to treat it different add a column such as "off-site".
-- Select data
select p.*, isnull(a.actual_hrs, 0) as hours
from planned as p
left join actual as a
on p.Operation1 = a.Operation1 and
p.Order1 = a.Order1
The technique is a left join with an isnull() on the field that has missing data. This will end up with our zero value.
Screen shot of sql fiddle.
Screen shot of output.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论