0

我有 2 个表,我想用表 2 中 id=id 的值更新表 1 中的一列。但是表 2 有很多行与表 1 匹配,表 2 的所有行都需要更新为表 1 中的 1 行

表_A

id |  all_names      |
---+-----------------+
1  |AB CD FG HI      |
2  |                 |  

** 表_B **

id | name  |
---+-------+
1  |       |
2  | Jon   | 
2  | Mike   |

更新后表 1 应如下所示

    id |  all_names      |
    ---+-----------------+
    1  |AB CD FG HI      |
    2  |Jon Mike         |  

我试过了

update a 
set a.all_names = TRIM(a.all_names) + b.name + ' '
from table_a a, table_b b
where a.id = b.id

我最终得到的只是 table_a 中的一个空 all_names

任何想法?

4

3 回答 3

0

除了通过循环之外,我真的看不到任何其他方法。

DECLARE @id int
DECLARE @name varchar(50)

SELECT * INTO #temp FROM TABLE_B

WHILE EXISTS (SELECT 1 FROM #temp)
BEGIN
SELECT @id = (SELECT TOP 1 id from #temp)
SELECT @name = (SELECT TOP 1 [name] from #temp where id = @id)

UPDATE A
SET all_names = LTRIM(RTRIM(all_names + CHAR(32) + @name))
FROM Table_A A
WHERE A.id = @id

DELETE FROM #temp WHERE id = @id and [name] = @name

END

DROP TABLE #temp

该查询将表 B 的内容放入一个临时表中,并在使用该行后将其删除。因此,基本上所有名称都通过循环为其自己的 ID 保持相同的值,除了每次都添加空格 + 下一个名称。我还为更新添加了修剪以防止前导/尾随空格。

于 2017-08-09T23:17:02.887 回答
0

我不知道这是否有帮助,但这是严格使用 SQL 的 Oracle 版本。你没有在你的要求中提到它,但是第二次合并可以防止行中的重复条目:

创建表并插入示例行

DROP TABLE table_a;
DROP TABLE table_b;

CREATE TABLE table_a
(
    id INTEGER
  , all_names VARCHAR2 (128)
);

CREATE TABLE table_b
(
    id INTEGER
  , name VARCHAR2 (10)
);

INSERT INTO table_a (id, all_names)
     VALUES (1, 'AB CD FG HI');

INSERT INTO table_a (id, all_names)
     VALUES (2, NULL);

INSERT INTO table_b (id, name)
     VALUES (1, NULL);

INSERT INTO table_b (id, name)
     VALUES (2, 'Jon');

INSERT INTO table_b (id, name)
     VALUES (2, 'Mike');

COMMIT;

合并允许重复

MERGE INTO table_a ta
     USING (SELECT DISTINCT id, LISTAGG (name, ' ') WITHIN GROUP (ORDER BY name) OVER (PARTITION BY id) names
              FROM table_b) tb
        ON (ta.id = tb.id)
WHEN MATCHED
THEN
    UPDATE SET all_names   = all_names || tb.names
WHEN NOT MATCHED
THEN
    INSERT     (
               ta.id, ta.all_names
               )
        VALUES (
                   tb.id, tb.names
               );

SELECT *
  FROM table_a;

ROLLBACK;

合并消除重复

MERGE INTO table_a ta
     USING (SELECT DISTINCT id, LISTAGG (name, ' ') WITHIN GROUP (ORDER BY name) OVER (PARTITION BY id) names
              FROM (WITH
                        aset
                        AS
                            (SELECT id, TRIM (all_names) || ' ' AS all_names
                               FROM table_a),
                        bset (id, name, REMAINDER)
                        AS
                            (SELECT id
                                  , SUBSTR (all_names, 1, INSTR (all_names, ' ') - 1) name
                                  , SUBSTR (all_names, INSTR (all_names, ' ') + 1) REMAINDER
                               FROM aset
                             UNION ALL
                             SELECT id
                                  , SUBSTR (REMAINDER, 1, INSTR (REMAINDER, ' ') - 1) name
                                  , SUBSTR (REMAINDER, INSTR (REMAINDER, ' ') + 1) REMAINDER
                               FROM bset
                              WHERE name IS NOT NULL)
                    SELECT id, name
                      FROM bset
                     WHERE name IS NOT NULL
                    UNION
                    SELECT id, name
                      FROM table_b
                     WHERE name IS NOT NULL)) tb
        ON (ta.id = tb.id)
WHEN MATCHED
THEN
    UPDATE SET all_names   = tb.names 
WHEN NOT MATCHED
THEN
    INSERT (ta.id, ta.all_names)
    VALUES (tb.id, tb.names);

SELECT *
  FROM table_a;

--ROLLBACK;
于 2017-08-09T23:46:51.623 回答
0

我最终做了什么

Declare @Crs cursor as select * from Table_B;   //Temp Table 
open @crs;
while fetch @crs do
update Table_A set all_names=ifnull(Table_B,'')+trim(@crs.name)+' ' where 
id=@Crs.id;
end while;
close @crs;

这使用最少的线条并且很优雅

于 2017-08-14T22:29:43.557 回答