我有tbl1
IDa | year | field2 |
----+------+---------
1 | 2015 | bbb |
2 | 2015 | aaa |
3 | 2015 | ccc |
---------------------
我正在使用INSERT INTO SELECT
复制2015年的所有数据,但将year
更改为2016
INSERT INTO tbl1 (year, field2) SELECT '2016', field2 from tbl1 WHERE year = '2015'
并返回这样的数据
IDa | year | field2 |
----+------+---------
1 | 2015 | bbb |
2 | 2015 | aaa |
3 | 2015 | ccc |
4 | 2016 | bbb |
5 | 2016 | aaa |
6 | 2016 | ccc |
---------------------
现在,我有另一个表tbl2
在[{1}}中有IDa
的外键,其关系是这样的一对多
tbl1
现在,使用IDb | year | IDa | field3 |
----+------+-----+---------
1 | 2015 | 1 | ddd |
2 | 2015 | 1 | eee |
3 | 2015 | 2 | fff |
4 | 2015 | 3 | ggg |
5 | 2015 | 3 | hhh |
6 | 2015 | 3 | iii |
---------------------------
,我还要复制INSERT INTO SELECT
中tbl2
的数据并将其更改为2016,但year
中的IDa
2016
我试过这个
year
但是这个查询收到错误,因为当时一个字段返回多个值。
那么,如何为此做出正确的查询?我希望结果是这样的
INSERT INTO tbl2 (year, IDa, field3)
SELECT year, (SELECT IDa FROM tbl1 WHERE year = '2016'), field3
FROM tbl2
WHERE year = '2015'
有可能吗?
我很感谢所有答案,谢谢你的帮助。
答案 0 :(得分:2)
就目前而言,您的子查询不会返回一行的IDa
,而是返回全年的所有值。 (这是一个问题,因为您无法将所有这些值放在一行中的一个字段中。)
要修复您的确切语法,您需要将子查询与您正在阅读的表“关联”,以便每行只获得一个结果,以便进行IDa查找...
不幸的是,在你的情况下,这会非常混乱。您需要在table1中查找原始IDa
的内容,然后在同一个表中查找匹配的行但是明年...
INSERT INTO
tbl2 (
year,
IDa,
field3
)
SELECT
year + 1,
(SELECT IDa
FROM tbl1
WHERE year = tbl2.year + 1
AND field2 = (SELECT field2
FROM tbl1
WHERE IDa = tbl2.IDa
)
),
field3
FROM
tbl2
WHERE
year = '2015'
也就是说,有一种更简单的方法,使用连接...
INSERT INTO
tbl2 (
year,
IDa,
field3
)
SELECT
newer.year,
newer.IDa,
tbl2.field3
FROM
tbl2
INNER JOIN
tbl1 older
ON older.IDa = tbl2.IDa
INNER JOIN
tbl1 newer
ON newer.year = older.year + 1
AND newer.field2 = older.field2
WHERE
tbl2.year = 2015
<强> 修改 强>
如果field2
不存在,您就会遇到在每种情况下都不知道选择IDa
的问题。
我认为有两种选择:
- 使用@PaulSpiegel的方法
- 手动引入代理
就个人而言,这听起来越来越复杂,基本的重新设计听起来似乎是有益的。
如果您无法重新设计或使用@PaulSpiegel中的方法,则可以选择...
INSERT INTO
tbl2 (
year,
IDa,
field3
)
WITH
ordered_tbl1
(
SELECT
ROW_NUMBER() OVER (PARTITION BY year ORDER BY year) AS ordinal,
tbl1.*
FROM
tbl1
)
SELECT
newer.year,
newer.IDa,
tbl2.field3
FROM
tbl2
INNER JOIN
ordered_tbl1 older
ON older.IDa = tbl2.IDa
INNER JOIN
ordered_tbl1 newer
ON newer.year = older.year + 1
AND newer.ordinal = older.ordinal
WHERE
tbl2.year = 2015
这假定tbl1
中的唯一字段为year
和IDa
。如果您在tbl1
中有其他字段,那么它们应该包含在ROW_NUMBER()
的{{1}}子句中,以确保这两行中的行显示的顺序相同。
如果这对您没有意义,那么您可能不应该使用它。而是重新设计或使用@PaulSpiegel的方法。
答案 1 :(得分:2)
将列oIDa
(原始ID)添加到tbl1
。
ALTER TABLE tbl1 ADD oIDa INT;
使用原始ID复制数据,以便日后使用。
INSERT INTO tbl1 (year, field2, oIDa) SELECT '2016', field2, IDa from tbl1 WHERE year = '2015';
现在您有一个可以加入的列,以查找新生成的IDa
值:
INSERT INTO tbl2 (year, IDa, field3)
SELECT year, tbl1.IDa, tbl2.field3
FROM tbl2
JOIN tbl1 ON tbl1.oIDa = tbl2.IDa
WHERE tbl2.year = 2015;
现在您可以删除新列:
ALTER TABLE tbl1 DROP COLUMN oIDa;
答案 2 :(得分:0)
我并不是100%了解您的数据 - 所以我不确定Field2和Field3每年是否总是相同。如果是,那么这应该有效:
<span ng-bind="data"></span>