在Oracle SQL中,更新包含范围值的列是否有更短的方法?

huangapple go评论78阅读模式
英文:

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

huangapple
  • 本文由 发表于 2020年1月6日 15:03:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/59607956.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定