如果这个问题基于解决方案 - Shuffle a column between rows - 我需要适用于此,一个新条件:名称必须保证性别:男性,女性或未知。
所以,我的表有一个名为gender
的列。我需要对同一性别的列进行洗牌。
我试过这个,但在某些情况下我无法保证性别
merge into original_table o
using (
with
helper ( id, gender, rn, rand_rn ) as (
select id,
gender,
row_number() over (order by id),
row_number() over (order by dbms_random.value())
from original_table
)
select ot.name, ot.gender, h2.id
from original_table ot inner join helper h1 on (ot.id = h1.id and ot.gender = h1.gender)
inner join helper h2 on h1.rand_rn = h2.rn
) p
on (o.id = p.id)
when matched then update set o.name = p.name
;
如果性别不可用(为空值),例如公司名称,则此合并不会更新任何内容。
我可以在3个不同的合并语句中拆分此查询。我拥有的每个性别一个。但我正在寻找一个更好,更简单的陈述。因为我需要在不同的环境和不同的条件下应用相同的解决方案。 感谢。
编辑:示例数据
ID GENDER NAME
3721 M MARK
3722 M JUSTIN
3723 F RUTH
3724 F MARY
3725 F ANNE
4639 CAMPANY SA
4640 M JOHN
4641 M LUCAS
4642 COMPANY HOLDER SA
一种可能的解决方案:
ID GENDER NAME
3721 M LUCAS
3722 M JOHN
3723 F MARY
3724 F ANNE
3725 F RUTH
4639 CAMPANY HOLDER SA
4640 M MARK
4641 M JUSTIN
4642 COMPANY SA
答案 0 :(得分:2)
在分析函数和PARTITION BY
子句中的JOIN
子句中包含性别。如果您没有匹配的主键,则可以使用ROWID
伪列。
Oracle安装程序:
CREATE TABLE original_table ( id, gender, name, company ) AS
SELECT 1, 'F', 'Alice', CAST( NULL AS VARCHAR2(20) ) FROM DUAL UNION ALL
SELECT 2, 'M', 'Bobby', 'ACME' FROM DUAL UNION ALL
SELECT 3, 'F', 'Carol', 'XYZ' FROM DUAL UNION ALL
SELECT 4, 'M', 'David', NULL FROM DUAL UNION ALL
SELECT 5, 'M', 'Errol', 'ACME' FROM DUAL UNION ALL
SELECT 6, 'F', 'Fiona', 'XYZ' FROM DUAL;
<强>更新强>:
MERGE INTO original_table dst
USING (
WITH rnd ( rid, rn, rnd_rn, gender, name ) AS (
SELECT ROWID,
ROW_NUMBER() OVER ( PARTITION BY gender ORDER BY id ),
ROW_NUMBER() OVER ( PARTITION BY gender ORDER BY DBMS_RANDOM.VALUE ),
gender,
name
FROM original_table
)
SELECT o.rid, r.name
FROM rnd o INNER JOIN rnd r
ON ( ( o.gender = r.gender OR ( o.gender IS NULL AND r.gender IS NULL ) )
AND o.rn = r.rnd_rn )
)
ON ( dst.ROWID = src.ROWID )
WHEN MATCHED THEN
UPDATE SET name = src.name;
<强>输出强>:
SELECT * FROM original_table;
ID G NAME COMPANY
-- - ----- -------
1 F Fiona
2 M David ACME
3 F Alice XYZ
4 M Bobby
5 M Errol ACME
6 F Carol XYZ