英文:
Updating existing fields with data from another field in the same row and data from another table - SQL Server 2019
问题
Here's the translated part:
我有一个名为TABLE1的表格,内容如下(只有几条记录):
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1837520919 | LineaA_Loria_Turn12 | 1500 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1812527159 | LineaD_Callao_Turn9 | 750 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1838404812 | LineaE_Virreyes_Turn5 | 750 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1843766323 | LineaC_Constitucion_Turn15 | 750 |
| 2022-08-01 | 1900-01-01 19:36:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1732054697 | LineaC_Retiro_Turn11 | 1500 |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1835202082 | LineaH_Hospitales_Turn1 | 3000 |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1828702502 | LineaC_Independencia_Turn6 | 1500 |
我需要从TABLE1中拆分codigo3字段,一部分将替换codigo1的值,另一部分将替换codigo4的值,就像这个例子中一样:
LineaC_Retiro_Turn11将被拆分为LineaC和Retiro(这里的Turn11部分没有用处),并应该将其自己的行从这个:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1828702502 | LineaC_Retiro_Turn11 | 1500 |
变成这样:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | LineaC | 1828702502 | LineaC_Retiro_Turn11 | Retiro |
但我还有另一个表,TABLE2,它将值LineaC(在这个例子中)与数字代码444链接在一起,我也想在执行UPDATE时将LineaC替换为该代码,如果可能的话。每个值Linea%都有自己的数字代码,而且只有很少的代码。因此,这个例子最终应该是这样的:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 444 | 1828702502 | LineaC_Retiro_Turn11 | Retiro |
TABLE1没有ID或PK。codigo2可能看起来像一个,但它会在TABLE1中重复n次;codigo1始终是相同的值;codigo4是一种费用,在TABLE1中也没有模式地重复(它只是一个费用),因此无法确定必须更新哪一行,除非将所有字段一起考虑,但我甚至不能保证这样做会起作用(主要是因为hora1和hora2字段没有秒,或者它们总是'00'),因此我必须依赖行号来进行这些更改,或者更改表以在新字段上添加序列作为ID。
无论是否有ID字段,如何才能使UPDATE以将TABLE1 codigo1替换为TABLE2中的数字值,并将TABLE1 codigo3的中间字符串替换为TABLE1 codigo4?
我正在使用以下查询进行拆分:
SELECT Reverse(ParseName(Replace(Reverse(codigo3), '_', '.'), 1)) AS part1,
Reverse(ParseName(Replace(Reverse(x.codigo3), '_', '.'), 2)) AS part2
FROM TABLE1
但它不仅返回一行,而是返回TABLE1中所有现有行,所以我需要仅选择与我要更新的同一行对应的“codigo3”值。
英文:
I have a table TABLE1 that goes like this (just a few records):
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1837520919 | LineaA_Loria_Turn12 | 1500 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1812527159 | LineaD_Callao_Turn9 | 750 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1838404812 | LineaE_Virreyes_Turn5 | 750 |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 612 | 1843766323 | LineaC_Constitucion_Turn15 | 750 |
| 2022-08-01 | 1900-01-01 19:36:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1732054697 | LineaC_Retiro_Turn11 | 1500 |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1835202082 | LineaH_Hospitales_Turn1 | 3000 |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1828702502 | LineaC_Independencia_Turn6 | 1500 |
I need to split the codigo3 field from TABLE1 so one part will replace codigo1 value and another part will replace codigo4 value, as in this example:
LineaC_Retiro_Turn11 will be split into LineaC and Retiro (the Turn11 part here is of no use) and should modify its own row from this:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 612 | 1828702502 | LineaC_Retiro_Turn11 | 1500 |
to this:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | LineaC | 1828702502 | LineaC_Retiro_Turn11 | Retiro |
But I have another table, TABLE2, that links the value LineaC (in this example) with a numerical code, 444, and I want also to replace that LineaC with that code, if possible at the same time I am performing the UPDATE. Every value Linea% has its own numeric code, and there are just a few codes. So this example should end up like this:
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 444 | 1828702502 | LineaC_Retiro_Turn11 | Retiro |
TABLE1 does not have an ID or a PK. codigo2, which could seem to be one, repeats itself alongside TABLE1 n times; codigo1 is always the same value; and codigo4 is a fare that also repeats itself in TABLE1 with no pattern (it's just a fare), so there is no way to tell which row must be updated unless you take all fields altogether, and I cannot assure that even that would work (mostly because the hour fields hora1 and hora2 don't have the seconds, or they are always '00'), so I have to rely on the row number to make those changes, or alter the table to add a sequence as an ID on a new field.
In either case, with or without an ID field, how do I make the update in order to get TABLE1 codigo1 replaced with the numeric value from TABLE2 and the middle string from TABLE1 codigo3 replacing TABLE1 codigo4?
I'm splitting using the following query:
SELECT Reverse(ParseName(Replace(Reverse(codigo3), '_', '.'), 1)
) AS part1,
Reverse(ParseName(Replace(Reverse(x.codigo3), '_', '.'), 2)
) AS part2
FROM TABLE1
But it does not return just one row but all the existing rows in TABLE1, so I need to select just the "codigo3" value corresponding to the same row I want to update.
答案1
得分: 1
我使用了CTE split来计算part1和new_codigo4的值。然后,将CTE与TABLE1和TABLE2连接,以更新TABLE1中的codigo1和codigo4字段。
-- 创建TABLE1
drop table if exists table1;
CREATE TABLE TABLE1 (
fecha1 DATE,
hora1 DATETIME,
fecha2 DATE,
hora2 DATETIME,
codigo1 VARCHAR(50),
codigo2 BIGINT,
codigo3 VARCHAR(50),
codigo4 VARCHAR(50)
);
drop table if exists table2;
-- 创建TABLE2
CREATE TABLE TABLE2 (
linea VARCHAR(10),
numeric_code INT
);
-- 将示例数据插入TABLE1
INSERT INTO TABLE1 (fecha1, hora1, fecha2, hora2, codigo1, codigo2, codigo3, codigo4)
VALUES
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '111', '1837520919', 'LineaA_Loria_Turn12', 'Loria'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '333', '1812527159', 'LineaD_Callao_Turn9', 'Callao'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '555', '1838404812', 'LineaE_Virreyes_Turn5', 'Virreyes'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '444', '1843766323', 'LineaC_Constitucion_Turn15', 'Constitucion'),
('2022-08-01', '1900-01-01 19:36:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '444', '1732054697', 'LineaC_Retiro_Turn11', 'Retiro'),
('2022-08-01', '1900-01-01 19:37:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '666', '1835202082', 'LineaH_Hospitales_Turn1', 'Hospitales'),
('2022-08-01', '1900-01-01 19:37:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '444', '1828702502', 'LineaC_Independencia_Turn6', 'Independencia');
-- 将示例数据插入TABLE2
INSERT INTO TABLE2 (linea, numeric_code)
VALUES
('LineaA', 111),
('LineaB', 222),
('LineaC', 444),
('LineaD', 333),
('LineaE', 555),
('LineaH', 666);
-- 使用CTE split进行计算
WITH split AS (
SELECT *,
LEFT(codigo3, CHARINDEX('_', codigo3) - 1) AS part1,
SUBSTRING(codigo3, CHARINDEX('_', codigo3) + 1, CHARINDEX('_', STUFF(codigo3, CHARINDEX('_', codigo3), 1, ' ')) - CHARINDEX('_', codigo3) - 1) AS new_codigo4
FROM TABLE1
)
-- 更新TABLE1中的数据
UPDATE t1
SET t1.codigo1 = t2.numeric_code,
t1.codigo4 = split.new_codigo4
FROM TABLE1 t1
JOIN split ON t1.codigo2 = split.codigo2
JOIN TABLE2 t2 ON t2.linea = split.part1;
-- 查询TABLE1中的数据
select * from table1
你的代码已被翻译,如有需要,可以继续使用。
英文:
I used a CTE split to calculate the part1 and new_codigo4 values. The CTE is then joined with TABLE1 and TABLE2 to update the codigo1 and codigo4 fields in TABLE1.
-- Create TABLE1
drop table if exists table1;
CREATE TABLE TABLE1 (
fecha1 DATE,
hora1 DATETIME,
fecha2 DATE,
hora2 DATETIME,
codigo1 VARCHAR(50),
codigo2 BIGINT,
codigo3 VARCHAR(50),
codigo4 VARCHAR(50)
);
drop table if exists table2;
-- Create TABLE2
CREATE TABLE TABLE2 (
linea VARCHAR(10),
numeric_code INT
);
-- Insert sample data into TABLE1
INSERT INTO TABLE1 (fecha1, hora1, fecha2, hora2, codigo1, codigo2, codigo3, codigo4)
VALUES
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '612', '1837520919', 'LineaA_Loria_Turn12', '1500'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '612', '1812527159', 'LineaD_Callao_Turn9', '750'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '612', '1838404812', 'LineaE_Virreyes_Turn5', '750'),
('2022-08-12', '1900-01-01 07:00:00.000', '2022-08-13', '1900-01-01 01:18:00.000', '612', '1843766323', 'LineaC_Constitucion_Turn15', '750'),
('2022-08-01', '1900-01-01 19:36:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '612', '1732054697', 'LineaC_Retiro_Turn11', '1500'),
('2022-08-01', '1900-01-01 19:37:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '612', '1835202082', 'LineaH_Hospitales_Turn1', '3000'),
('2022-08-01', '1900-01-01 19:37:00.000', '2022-08-02', '1900-01-01 01:01:00.000', '612', '1828702502', 'LineaC_Independencia_Turn6', '1500');
-- Insert sample data into TABLE2
INSERT INTO TABLE2 (linea, numeric_code)
VALUES
('LineaA', 111),
('LineaB', 222),
('LineaC', 444),
('LineaD', 333),
('LineaE', 555),
('LineaH', 666);
WITH split AS (
SELECT *,
LEFT(codigo3, CHARINDEX('_', codigo3) - 1) AS part1,
SUBSTRING(codigo3, CHARINDEX('_', codigo3) + 1, CHARINDEX('_', STUFF(codigo3, CHARINDEX('_', codigo3), 1, ' ')) - CHARINDEX('_', codigo3) - 1) AS new_codigo4
FROM TABLE1
)
UPDATE t1
SET t1.codigo1 = t2.numeric_code,
t1.codigo4 = split.new_codigo4
FROM TABLE1 t1
JOIN split ON t1.codigo2 = split.codigo2
JOIN TABLE2 t2 ON t2.linea = split.part1;
select * from table1
| fecha1 | hora1 | fecha2 | hora2 | codigo1 | codigo2 | codigo3 | codigo4 |
|---|---|---|---|---|---|---|---|
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 111 | 1837520919 | LineaA_Loria_Turn12 | Loria |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 333 | 1812527159 | LineaD_Callao_Turn9 | Callao |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 555 | 1838404812 | LineaE_Virreyes_Turn5 | Virreyes |
| 2022-08-12 | 1900-01-01 07:00:00.000 | 2022-08-13 | 1900-01-01 01:18:00.000 | 444 | 1843766323 | LineaC_Constitucion_Turn15 | Constitucion |
| 2022-08-01 | 1900-01-01 19:36:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 444 | 1732054697 | LineaC_Retiro_Turn11 | Retiro |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 666 | 1835202082 | LineaH_Hospitales_Turn1 | Hospitales |
| 2022-08-01 | 1900-01-01 19:37:00.000 | 2022-08-02 | 1900-01-01 01:01:00.000 | 444 | 1828702502 | LineaC_Independencia_Turn6 | Independencia |
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论