英文:
Is there a shorter way to update a column with range values on Oracle SQL?
问题
更新脚本将如下所示:
UPDATE TABLE_A
SET COLUMN_A = (范围值 (1,10))
WHERE COLUMN_B = 'Descriptions';
因此,当我运行以下查询:
SELECT COLUMN_B, min(COLUMN_A), max(COLUMN_A)
FROM TABLE_A
WHERE COLUMN_B = 'Descriptions'
GROUP BY COLUMN_B;
COLUMN_A 的最小值为 1,最大值为 10。
英文:
The update script will be like
UPDATE TABLE_A
SET COLUMN_A = (range values (1,10)
WHERE COLUMN_B = 'Descriptions'
So that when I run the query below
SELECT COLUMN_B, min(COLUMN_A ), max(COLUMN_A )
FROM TABLE_A
WHERE COLUMN_B = 'Descriptions'
group by COLUMN_B ;
COLUMN_A has minimum value of 1 and maximum value of 10.
答案1
得分: 0
UPDATE TABLE_A
SET COLUMN_A = CEIL(DBMS_RANDOM.VALUE * 10)
WHERE COLUMN_B = 'Descriptions';
在Oracle中没有“ranges”函数,但您可以使用dbms_random来模拟它,该函数生成0到1之间的值。将其乘以10,以便获得0到10之间的值(10不包括在内)。使用CEIL
函数四舍五入,以便获得1到10的值。
请注意,在此示例中,您将获得1到10之间的随机值,不能保证包括值1和10,并且可能会有重复值。
英文:
UPDATE TABLE_A
SET COLUMN_A = CEIL(DBMS_RANDOM.VALUE * 10)
WHERE COLUMN_B = 'Descriptions';
There is no "ranges" function in oracle, but you can emulate that using dbms_random which generates a value between 0 an 1. Multiply it by 10 so you get a value between 0 and 10 (10 will not be included). Round up (using CEIL
function) so you get values 1 thru 10.
Note that you will get random values between 1 and 10 in this example, there is no guarantee you have values 1 and 10 included and there will likely be duplicates.
答案2
得分: 0
以下是翻译好的部分:
让我们假设您有一些示例数据:
CREATE TABLE table_a ( Column_A, Column_B ) AS
SELECT 0, 'Descriptions' FROM DUAL UNION ALL
SELECT 100, 'Descriptions' FROM DUAL UNION ALL
SELECT 3, 'Range1' FROM DUAL UNION ALL
SELECT 5, 'Range2' FROM DUAL UNION ALL
SELECT 6, 'Range2' FROM DUAL UNION ALL
SELECT 7, 'Range2' FROM DUAL;
而您想要将 Descriptions
更新为从1到10的范围,并且还希望将 Range1
更新为从42到50的范围(但示例数据中只有一行),以及将 Range2
更新为从0到9的范围(但示例数据中有两行以上)。然后,您可以使用 MERGE
语句:
MERGE INTO table_a dst
USING (
WITH ranges ( Column_A, Column_B, rn ) AS (
SELECT 1, 'Descriptions', 1 FROM DUAL UNION ALL
SELECT 10, 'Descriptions', 0 FROM DUAL UNION ALL
SELECT 42, 'Range1', 1 FROM DUAL UNION ALL
SELECT 50, 'Range1', 0 FROM DUAL UNION ALL
SELECT 0, 'Range2', 1 FROM DUAL UNION ALL
SELECT 9, 'Range2', 0 FROM DUAL
)
SELECT r.Column_A,
r.Column_B,
a.rid
FROM ranges r
LEFT OUTER JOIN (
SELECT ROWID AS rid,
ROW_NUMBER() OVER ( PARTITION BY Column_B ORDER BY ROWNUM ) AS rn,
Column_B
FROM table_a
) a
ON ( r.Column_B = a.Column_B AND MOD( a.rn, 2 ) = r.rn )
) src
ON ( src.rid = dst.ROWID )
WHEN MATCHED THEN
UPDATE SET Column_A = src.Column_A
WHEN NOT MATCHED THEN
INSERT ( Column_A, Column_B )
VALUES ( src.Column_A, src.Column_B );
输出结果将是:
SELECT * FROM table_a;
COLUMN_A | COLUMN_B
-------: | :-----------
1 | Descriptions
10 | Descriptions
42 | Range1
0 | Range2
9 | Range2
0 | Range2
50 | Range1
您可以看到已经创建了额外一行 Range1
,并且所有 Range2
的行都已更新。
英文:
Lets assume that you have some sample data:
CREATE TABLE table_a ( Column_A, Column_B ) AS
SELECT 0, 'Descriptions' FROM DUAL UNION ALL
SELECT 100, 'Descriptions' FROM DUAL UNION ALL
SELECT 3, 'Range1' FROM DUAL UNION ALL
SELECT 5, 'Range2' FROM DUAL UNION ALL
SELECT 6, 'Range2' FROM DUAL UNION ALL
SELECT 7, 'Range2' FROM DUAL;
And you want to update Descriptions
to have a range from 1-10 and also want to update Range1
to have a range from 42-50 (but there is only a single row in the sample data) and Range2
to have a range from 0-9 (but there are more than two rows in the sample data). Then you can use a MERGE
statement:
MERGE INTO table_a dst
USING (
WITH ranges ( Column_A, Column_B, rn ) AS (
SELECT 1, 'Descriptions', 1 FROM DUAL UNION ALL
SELECT 10, 'Descriptions', 0 FROM DUAL UNION ALL
SELECT 42, 'Range1', 1 FROM DUAL UNION ALL
SELECT 50, 'Range1', 0 FROM DUAL UNION ALL
SELECT 0, 'Range2', 1 FROM DUAL UNION ALL
SELECT 9, 'Range2', 0 FROM DUAL
)
SELECT r.Column_A,
r.Column_B,
a.rid
FROM ranges r
LEFT OUTER JOIN (
SELECT ROWID AS rid,
ROW_NUMBER() OVER ( PARTITION BY Column_B ORDER BY ROWNUM ) AS rn,
Column_B
FROM table_a
) a
ON ( r.Column_B = a.Column_B AND MOD( a.rn, 2 ) = r.rn )
) src
ON ( src.rid = dst.ROWID )
WHEN MATCHED THEN
UPDATE SET Column_A = src.Column_A
WHEN NOT MATCHED THEN
INSERT ( Column_A, Column_B )
VALUES ( src.Column_A, src.Column_B );
And the output would be:
SELECT * FROM table_a;
> <pre>
> COLUMN_A | COLUMN_B
> -------: | :-----------
> 1 | Descriptions
> 10 | Descriptions
> 42 | Range1
> 0 | Range2
> 9 | Range2
> 0 | Range2
> 50 | Range1
> </pre>
You can see that an extra row for Range1
has been created and all the rows for Range2
have been updated.
db<>fiddle here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论