我在MySQL上使用这两个表格。
select emp_id, contrato_id,date from organização_rh;
+--------+-------------+------------+
| emp_id | contrato_id | date |
+--------+-------------+------------+
| 1 | 1 | 2000-01-01 |
| 1 | 2 | 2000-01-10 |
| 1 | 3 | 2000-02-01 |
| 2 | 1 | 1999-01-01 |
+--------+-------------+------------+
select id, codigo from contratotipo;
+----+---------------+
| id | codigo |
+----+---------------+
| 2 | determinado |
| 3 | fim |
| 1 | indeterminado |
+----+---------------+
我要做的是以一种员工没有签订合同的方式加入他们,将日期字段设置为NULL。也就是说,我希望输出如下:
+--------+-------------+------------+
| emp_id | contrato_id | date |
+--------+-------------+------------+
| 1 | 1 | 2000-01-01 |
| 1 | 2 | 2000-01-10 |
| 1 | 3 | 2000-02-01 |
| 2 | 1 | 1999-01-01 |
| 2 | 2 | NULL |
| 2 | 3 | NULL |
+--------+-------------+------------+
我尝试过不同的连接但无效,到目前为止,它们都没有显示我在日期字段中有一个NULL值的行。所以,例如,如果我运行
SELECT emp_id,contrato_id, date
FROM organização_rh as o right outer JOIN contratotipo c
ON o.contrato_id = c.id;
当行不匹配时,我没有得到任何NULL值。
+--------+-------------+------------+
| emp_id | contrato_id | date |
+--------+-------------+------------+
| 1 | 3 | 2000-02-01 |
| 1 | 2 | 2000-01-10 |
| 1 | 1 | 2000-01-01 |
| 2 | 1 | 1999-01-01 |
+--------+-------------+------------+
任何帮助都将非常感谢!!
@John Ruddell感谢您的帮助。 我想出了这个不太优雅的解决方案,因为它使用游标,但它适用于任意数量的员工和合同。您的解决方案似乎更加轻松,因为一切只适合一个查询。但是,我无法将其改编为更一般的案例。
BEGIN
declare var_contrato_id int unsigned;
declare contrato_finished int default 0;
DECLARE contrato_cursor CURSOR FOR SELECT id FROM contratotipo;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET contrato_finished = 1;
OPEN contrato_cursor;
drop table if exists temp_sp_rh_turnover;
CREATE TEMPORARY TABLE temp_sp_rh_turnover AS (select distinct org_id, emp_id, cast( 0 AS unsigned) as contrato_id, cast('1000-1-1' as date) as data from organização_rh where emp_id=-1);
conts: LOOP
FETCH contrato_cursor INTO var_contrato_id;
IF contrato_finished = 1 THEN
LEAVE conts;
END IF;
insert into temp_sp_rh_turnover
select distinct org_id, emp_id, var_contrato_id, NULL from organização_rh;
end loop;
select
t.org_id, t.emp_id, t.contrato_id, o.data
from
temp_sp_rh_turnover as t
left join
organização_rh as o
on
t.org_id = o.org_id and
t.emp_id = o.emp_id and
t.contrato_id = o.contrato_id;
drop table if exists temp_sp_rh_turnover;
END
答案 0 :(得分:0)
将表连接到自身。类似的东西:
select emp_id, contrato_id,date from organização_rh as a
JOIN
SELECT DISTINCT contrato_id FROM organização_rh as b
WHERE a.contrato_id = b.contrato_id
应该有用。
或者你可以
select emp_id, contrato_id,date from organização_rh as a
JOIN
select DISTINCT id from contratotipo as b
WHERE a.contrato_id = b.id
如果那更符合您的喜好。
答案 1 :(得分:0)
您遇到麻烦的原因是,如果没有列出所有员工的第三个表,您就无法做到这一点。
您可能认为可以使用
获取此信息select distinct emp_id from organização_rh
但这不包括员工未签署任何合同的情况。当然,您希望该员工出现在所有合同的空日期输出中。
创建一个employee
表,然后连接应该是显而易见的。
答案 2 :(得分:0)
在mysql中做这样的事情并不容易,这需要大量的手工工作。从我的理解,你想在你的另一个表中每行显示一个新行..
含义
对于表o中的每个 emp_id
,您希望有3行与之相关,其中一行与表c中的三行相关。
现在做类似的事情并不简单,因为没有办法手动添加行,除非您正在进行插入或一堆联合。因此,使用此数据集(我假设与您使用的数据相比较小),您可以获得这样的预期结果。
SET @row_num := 1;
INSERT INTO organização_rh (emp_id, contrato_id, date)
SELECT
emp_id, @ROW_NUM := @ROW_NUM + 1, NULL
FROM organização_rh
WHERE emp_id IN
( SELECT emp_id
FROM organização_rh
GROUP BY emp_id
HAVING COUNT(*) < 3
)
AND @ROW_NUM < 3;
运行此插入查询两次,我将为您提供所需的输出。
输出:
23:20:25 set @row_num := 1 0 row(s) affected 0.000 sec
23:20:30 INSERT INTO organização_rh (emp_id, contrato_id, date) SELECT emp_id, @ROW_NUM := @ROW_NUM + 1, NULL FROM organização_rh WHERE emp_id IN ( SELECT emp_id FROM organização_rh GROUP BY emp_id HAVING COUNT(*) < 3 ) AND @ROW_NUM < 3 1 row(s) affected Records: 1 Duplicates: 0 Warnings: 0 0.001 sec
23:20:31 INSERT INTO organização_rh (emp_id, contrato_id, date) SELECT emp_id, @ROW_NUM := @ROW_NUM + 1, NULL FROM organização_rh WHERE emp_id IN ( SELECT emp_id FROM organização_rh GROUP BY emp_id HAVING COUNT(*) < 3 ) AND @ROW_NUM < 3 1 row(s) affected Records: 1 Duplicates: 0 Warnings: 0 0.001 sec
23:20:32 INSERT INTO organização_rh (emp_id, contrato_id, date) SELECT emp_id, @ROW_NUM := @ROW_NUM + 1, NULL FROM organização_rh WHERE emp_id IN ( SELECT emp_id FROM organização_rh GROUP BY emp_id HAVING COUNT(*) < 3 ) AND @ROW_NUM < 3 0 row(s) affected Records: 0 Duplicates: 0 Warnings: 0 0.002 sec
如果您注意到我最后一次尝试这样做,就不会这样做,因为行数最大化了。这将是一些手工劳动,但它基本上只是在mysql中完成它的唯一方法。
插入后是结果集。
+-------+---------------+---------------+
|emp_id | contrato_id, | date |
+-------+---------------+---------------+
|'1', | '1', | '2000-01-01'|
|'1', | '2', | '2000-01-10'|
|'1', | '3', | '2000-02-01'|
|'2', | '1', | '1999-01-01'|
|'2', | '2', | NULL |
|'2', | '3', | NULL |
+-------+---------------+---------------+
注意:这是用于更新表格。如果你想只是一个带有这个输出的查询,你需要为每一个并不真正推荐的新行联合。说实话,你需要修复你的表结构。添加一个您可以进行笛卡尔积加入的列或其他内容。
无论如何这里是联合查询。
SELECT emp_id, contrato_id, date FROM organização_rh
CROSS JOIN(SELECT @ROW_NUM := 0)t
UNION ALL
SELECT
emp_id, @ROW_NUM := @ROW_NUM + 1, NULL
FROM
organização_rh
WHERE emp_id IN
( SELECT emp_id
FROM organização_rh
GROUP BY emp_id
HAVING COUNT(*) < 3
)
AND @ROW_NUM < 3
UNION ALL
SELECT
emp_id, @ROW_NUM := @ROW_NUM + 1, NULL
FROM
organização_rh
WHERE emp_id IN
( SELECT emp_id
FROM organização_rh
GROUP BY emp_id
HAVING COUNT(*) < 3
)
AND @ROW_NUM < 3;
OUTPUT 再次与插入
相同+-------+---------------+---------------+
|emp_id | contrato_id, | date |
+-------+---------------+---------------+
|'1', | '1', | '2000-01-01'|
|'1', | '2', | '2000-01-10'|
|'1', | '3', | '2000-02-01'|
|'2', | '1', | '1999-01-01'|
|'2', | '2', | NULL |
|'2', | '3', | NULL |
+-------+---------------+---------------+
答案 3 :(得分:0)
@John Ruddell
这适用于原始值。 我添加了一个新员工:emp_id = 3,contrato_id = 1,date = 2001-1-1。如果我运行查询,我会得到合同3(对于emp_id = 3)。
|emp_id|contrato_id| date |
+------+-----------+------------+
|'1', | '1', |'2000-01-01'|
|'1', | '2', |'2000-01-10'|
|'1', | '3', |'2000-02-01'|
|'2', | '1', |'1999-01-01'|
|'2', | '2', | NULL |
|'2', | '3', | NULL |
|'3', | '1', |'2001-01-01'|
|'3', | '2', | NULL |
我是否必须运行查询:
SELECT
emp_id, @ROW_NUM := @ROW_NUM + 1, NULL
FROM
organização_rh
WHERE emp_id IN
( SELECT emp_id
FROM organização_rh
GROUP BY emp_id
HAVING COUNT(*) < 3
)
AND @ROW_NUM < 3
重置@ROW_NUM后,每个用户?