English 中文(简体)
在查询Oracle SQL中创建替代ID
原标题:Create an alternative ID in query Oracle SQL

I am trying to add a column in a SQL query to use as an alternative ID. The data has this format:

UserID | Value
---------------
1      | 23
2      | 10
1      | 45

我想创建另一列,这是另一个数字,但尊重ID的唯一性。像这样

MaskedID | Value
---------------
9      | 23
8      | 10
9      | 45

我曾尝试使用子查询创建一个带有随机数的表,但第一个ID的随机数不保持不变:

Select b.Masked, a.value
from table a
left join 
(select distinct(UserID), dbms_random.value(1,100000) as Masked) b on a.UserID=b.UserID

但这会导致:

MaskedID | Value
---------------
7      | 23
8      | 10
9      | 45

用户ID的#可能会随着时间的推移而变化,因此不应该预先定义。CTE是否会阻止随机数在最终表中再生?

最佳回答

尝试哈希函数。它将始终为相同的输入返回相同的值,但不能反向工程到原始值。最古老和最简单的是ORA_HASH

select ORA_HASH(USERID) Masked, a.value
from table a

这会产生一个数字,但如果有足够的值,可能会发生碰撞。更好的是较新的STANDARD_HASH函数,它不太可能产生冲突,但会产生字母数字(十六进制)输出:

select STANDARD_HASH(USERID) Masked, a.value
from table a
问题回答

您可以为每个UserId中的第一个生成GUID ,然后使用分析函数为具有相同UserId的所有其他行使用相同的值:

SELECT MAX(maskedid) OVER (PARTITION BY userid) AS maskedid,
       value
FROM   (
  SELECT CASE ROW_NUMBER() OVER (PARTITION BY userid ORDER BY ROWNUM)
         WHEN 1
         THEN SYS_GUID()
         END AS maskedid,
         userid,
         value
  FROM   table_name
);

其中,对于示例数据:

CREATE TABLE table_name (UserID, Value) AS
SELECT 1, 23 FROM DUAL UNION ALL
SELECT 2, 10 FROM DUAL UNION ALL
SELECT 1, 45 FROM DUAL;

可输出:

MASKEDID VALUE
0x0BFDC951F97909BCE06502163E386F05 23
0x0BFDC951F97909BCE06502163E386F05 45
0x0BFDC951F97A09BCE06502163E386F05 10

您可以使用任何函数而不是SYS_GUID () ,例如DBMS_RANDOM.VALUE

SELECT MAX(maskedid) OVER (PARTITION BY userid) AS maskedid,
       value
FROM   (
  SELECT CASE ROW_NUMBER() OVER (PARTITION BY userid ORDER BY ROWNUM)
         WHEN 1
         THEN DBMS_RANDOM.VALUE(0, 1e6)
         END AS maskedid,
         userid,
         value
  FROM   table_name
);

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 31 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

MASKEDID VALUE
84046.38920350070167103410156941056149 23
84046.38920350070167103410156941056149 45
297835.63547525613908362909300172303338 10

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 29 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 27 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

Select 987654321 - a.USER_ID AS MaskedID, a.value
from table a;

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 26 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 24 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

select col1, col2, SYS_GUID() uniqueId from table1

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 23 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

select col1, col2, ROWID uniqueId from table1

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 21 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE

select col1, col2, ROWNUM uniqueId from table1

MYMEMORY WARNING: YOU USED ALL AVAILABLE FREE TRANSLATIONS FOR TODAY. NEXT AVAILABLE IN 23 HOURS 58 MINUTES 20 SECONDS VISIT HTTPS://MYMEMORY.TRANSLATED.NET/DOC/USAGELIMITS.PHP TO TRANSLATE MORE





相关问题
Export tables from SQL Server to be imported to Oracle 10g

I m trying to export some tables from SQL Server 2005 and then create those tables and populate them in Oracle. I have about 10 tables, varying from 4 columns up to 25. I m not using any constraints/...

Connecting to Oracle 10g with ODBC from Excel VBA

The following code works. the connection opens fine but recordset.recordCount always returns -1 when there is data in the table. ANd If I try to call any methods/properties on recordset it crashes ...

How to make a one to one left outer join?

I was wondering, is there a way to make a kind of one to one left outer join: I need a join that matches say table A with table B, for each record on table A it must search for its pair on table B, ...

Insert if not exists Oracle

I need to be able to run an Oracle query which goes to insert a number of rows, but it also checks to see if a primary key exists and if it does, then it skips that insert. Something like: INSERT ALL ...

How can I store NULLs in NOT NULL field?

I just came across NULL values in NOT-NULL fields in our test database. How could they get there? I know that NOT-NULL constraints can be altered with NOVALIDATE clause, but that would change table s ...

Type reference scope

I m studying databases and am currently working on a object-relational DB project and I ve encountered a small problem with the number of possible constraints in an object table. I m using "Database ...

OracleParameter and DBNull.Value

we have a table in an Oracle Database which contains a column with the type Char(3 Byte). Now we use a parameterized sql to select some rows with a DBNull.Value and it doesn t work: OracleCommand ...

热门标签