如何在连接两个不同的表时创建一个值为0的值?

huangapple go评论58阅读模式
英文:

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的屏幕截图:

如何在连接两个不同的表时创建一个值为0的值?

输出的屏幕截图:

如何在连接两个不同的表时创建一个值为0的值?

英文:

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.

如何在连接两个不同的表时创建一个值为0的值?

Screen shot of output.

如何在连接两个不同的表时创建一个值为0的值?

huangapple
  • 本文由 发表于 2023年3月3日 22:16:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/75628208.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定