oracle - 合并多个列值
oracle - merge multiple column values
我有以下数据集:
DAILY_DATA:
DEPT
CLASS
DATE
BOOK_ID
TRANSFER_RETAIL
TRANSFER_COST
100
1
10-APR
100
23.4
54
100
1
10-APR
200
0
92
我想合并 TRANSFER_RETAIL 和 TRANSFER_COST 的值
并将其添加到 BOOK_ID = 100
所在的行
因此该行将显示:
DEPT
CLASS
DATE
BOOK_ID
TRANSFER_RETAIL
TRANSFER_COST
100
1
10-APR
100
23.4
146
100
1
10-APR
200
0
92
我该怎么做?
与其将它们合并到一个已经存在的列中,不如添加一个新的虚拟列
比如
ALTER TABLE daily_data
ADD (
transfer_total AS ( transfer_retail+transfer_cost )
);
它不会在数据段内占用任何额外的 space,只是用于始终根据这两列显示所需的计算值。顺便说一句,您当前列的值 transfer_cost
将保留为原始值,并且 table 的规范化规则将受到保护。
我建议创建一个VIEW比修改原始数据更好。这避免了更新查询 运行 两次等所有风险,并且原始数据始终可用。
CREATE TABLE DAILY_DATA(DEPT INT,CLASS int, "DATE" DATE,BOOK_ID INT, TRANSFER_RETAIL DECIMAL(5,2),TRANSFER_COST DECIMAL(5,2));
INSERT INTO DAILY_DATA
SELECT 100, 1,to_date('2022-04-10','yyyy-mm-dd'),100,23.4,54 FROM dual UNION ALL
SELECT 100, 1,to_date('2022-04-10','yyyy-mm-dd'), 200, 0, 92 FROM dual
CREATE VIEW TOTALLED AS
SELECT
DEPT,
CLASS,
"DATE",
BOOK_ID,
CASE WHEN BOOK_ID = 100 THEN SUM(TRANSFER_RETAIL) OVER(partition BY "DATE")
ELSE TRANSFER_RETAIL end TRANSFER_RETAIL,
CASE WHEN BOOK_ID = 100 THEN SUM(TRANSFER_COST) OVER(partition BY "DATE")
ELSE TRANSFER_COST end TRANSFER_COST
from DAILY_DATA;
SELECT * FROM TOTALLED;
DEPT | CLASS | DATE | BOOK_ID | TRANSFER_RETAIL | TRANSFER_COST
---: | ----: | :-------- | ------: | --------------: | ------------:
100 | 1 | 10-APR-22 | 200 | 0 | 92
100 | 1 | 10-APR-22 | 100 | 23.4 | 146
db<>fiddle here
您可以使用 MERGE
语句来合并行:
MERGE INTO daily_data dst
USING (
SELECT dept,
class,
"DATE",
SUM(transfer_retail) AS transfer_retail,
SUM(transfer_cost) AS transfer_cost
FROM daily_data
WHERE book_id = 200
-- AND dept = 100
-- AND class = 1
-- AND "DATE" = DATE '2022-04-10'
GROUP BY dept, class, "DATE"
) src
ON ( dst.book_id = 100
AND dst.dept = src.dept
AND dst.class = src.class
AND dst."DATE" = src."DATE")
WHEN MATCHED THEN
UPDATE
SET transfer_retail = dst.transfer_retail + src.transfer_retail,
transfer_cost = dst.transfer_cost + src.transfer_cost;
其中,对于示例数据:
CREATE TABLE DAILY_DATA (DEPT, CLASS, "DATE", BOOK_ID, TRANSFER_RETAIL, TRANSFER_COST) AS
SELECT 100, 1, DATE '2022-04-10', 100, 23.4, 54 FROM DUAL UNION ALL
SELECT 100, 1, DATE '2022-04-10', 200, 0, 92 FROM DUAL;
然后在 MERGE
之后,table 将包含:
DEPT
CLASS
DATE
BOOK_ID
TRANSFER_RETAIL
TRANSFER_COST
100
1
10-APR-22
100
23.4
146
100
1
10-APR-22
200
0
92
db<>fiddle here
我有以下数据集:
DAILY_DATA:
DEPT | CLASS | DATE | BOOK_ID | TRANSFER_RETAIL | TRANSFER_COST |
---|---|---|---|---|---|
100 | 1 | 10-APR | 100 | 23.4 | 54 |
100 | 1 | 10-APR | 200 | 0 | 92 |
我想合并 TRANSFER_RETAIL 和 TRANSFER_COST 的值 并将其添加到 BOOK_ID = 100
所在的行因此该行将显示:
DEPT | CLASS | DATE | BOOK_ID | TRANSFER_RETAIL | TRANSFER_COST |
---|---|---|---|---|---|
100 | 1 | 10-APR | 100 | 23.4 | 146 |
100 | 1 | 10-APR | 200 | 0 | 92 |
我该怎么做?
与其将它们合并到一个已经存在的列中,不如添加一个新的虚拟列 比如
ALTER TABLE daily_data
ADD (
transfer_total AS ( transfer_retail+transfer_cost )
);
它不会在数据段内占用任何额外的 space,只是用于始终根据这两列显示所需的计算值。顺便说一句,您当前列的值 transfer_cost
将保留为原始值,并且 table 的规范化规则将受到保护。
我建议创建一个VIEW比修改原始数据更好。这避免了更新查询 运行 两次等所有风险,并且原始数据始终可用。
CREATE TABLE DAILY_DATA(DEPT INT,CLASS int, "DATE" DATE,BOOK_ID INT, TRANSFER_RETAIL DECIMAL(5,2),TRANSFER_COST DECIMAL(5,2));
INSERT INTO DAILY_DATA SELECT 100, 1,to_date('2022-04-10','yyyy-mm-dd'),100,23.4,54 FROM dual UNION ALL SELECT 100, 1,to_date('2022-04-10','yyyy-mm-dd'), 200, 0, 92 FROM dual
CREATE VIEW TOTALLED AS SELECT DEPT, CLASS, "DATE", BOOK_ID, CASE WHEN BOOK_ID = 100 THEN SUM(TRANSFER_RETAIL) OVER(partition BY "DATE") ELSE TRANSFER_RETAIL end TRANSFER_RETAIL, CASE WHEN BOOK_ID = 100 THEN SUM(TRANSFER_COST) OVER(partition BY "DATE") ELSE TRANSFER_COST end TRANSFER_COST from DAILY_DATA;
SELECT * FROM TOTALLED;
DEPT | CLASS | DATE | BOOK_ID | TRANSFER_RETAIL | TRANSFER_COST ---: | ----: | :-------- | ------: | --------------: | ------------: 100 | 1 | 10-APR-22 | 200 | 0 | 92 100 | 1 | 10-APR-22 | 100 | 23.4 | 146
db<>fiddle here
您可以使用 MERGE
语句来合并行:
MERGE INTO daily_data dst
USING (
SELECT dept,
class,
"DATE",
SUM(transfer_retail) AS transfer_retail,
SUM(transfer_cost) AS transfer_cost
FROM daily_data
WHERE book_id = 200
-- AND dept = 100
-- AND class = 1
-- AND "DATE" = DATE '2022-04-10'
GROUP BY dept, class, "DATE"
) src
ON ( dst.book_id = 100
AND dst.dept = src.dept
AND dst.class = src.class
AND dst."DATE" = src."DATE")
WHEN MATCHED THEN
UPDATE
SET transfer_retail = dst.transfer_retail + src.transfer_retail,
transfer_cost = dst.transfer_cost + src.transfer_cost;
其中,对于示例数据:
CREATE TABLE DAILY_DATA (DEPT, CLASS, "DATE", BOOK_ID, TRANSFER_RETAIL, TRANSFER_COST) AS
SELECT 100, 1, DATE '2022-04-10', 100, 23.4, 54 FROM DUAL UNION ALL
SELECT 100, 1, DATE '2022-04-10', 200, 0, 92 FROM DUAL;
然后在 MERGE
之后,table 将包含:
DEPT CLASS DATE BOOK_ID TRANSFER_RETAIL TRANSFER_COST 100 1 10-APR-22 100 23.4 146 100 1 10-APR-22 200 0 92
db<>fiddle here