【问题标题】:Dynamically generate unique primary key for a column composition in a T-SQL SELECT statement为 T-SQL SELECT 语句中的列组合动态生成唯一主键
【发布时间】:2019-03-21 04:51:14
【问题描述】:

有人知道是否有办法在 MS SQL Server / Transact SQL SELECT 语句中生成唯一的整数主键?

我遇到的问题是,我必须通过列组合(如复合主键)以编程方式合并 3 个数据表。组合不是实际的主键。

我的表格有点像这样:

Table 1: Base Table which is needed to be filled: 
+----------+------+----------------+------------+----------+
|operatorid|opcode|bookkeeping_date|cash_amount |tip_amount|
+----------+------+----------------+------------+----------+
| 1        | 1    | 01.01.2018     |null        |null      |
+----------+------+----------------+------------+----------+
| 1        | 1    | 01.02.2018     |null        |null      |
+----------+------+----------------+------------+----------+
| 2        | 2    | 01.02.2018     |null        |null      |
+----------+------+----------------+------------+----------+

Table 2: Cash Data Table to be merged with base table
+----------+------+----------------+------------+
|operatorid|opcode|bookkeeping_date|cash_amount |
+----------+------+----------------+------------+
| 1        | 1    | 01.01.2018     |2.50        |
+----------+------+----------------+------------+
| 1        | 1    | 01.02.2018     |17.80       |
+----------+------+----------------+------------+
| 2        | 2    | 01.02.2018     |4.20        |
+----------+------+----------------+------------+

Table 3: Tip Data Table to be merged with base table: 
+----------+------+----------------+----------+
|operatorid|opcode|bookkeeping_date|tip_amount|
+----------+------+----------------+----------+
| 1        | 1    | 01.01.2018     |3.50      |
+----------+------+----------------+----------+
| 1        | 1    | 01.02.2018     |4.20      |
+----------+------+----------------+----------+
| 2        | 2    | 01.02.2018     |0.00      |
+----------+------+----------------+----------+

如此简化的目标是通过合并数据表来填充“表 1:基表”。我们已经有了一个 c# 方法,可以在选择数据表后通过主键管理合并。

我现在的问题是我没有唯一的主键,而是“operatorid”和“bookkeeping_date”的组合。

有没有一种方法可以修改每个表的 SELECT 语句,以通过哈希或校验和或类似的东西获得唯一的整数?

编辑:现金金额和小费金额是表选择语句中使用聚合 SUM() 的总和。

最好的问候

百里香

【问题讨论】:

  • 你看过ROW_NUMBER吗?
  • 可以通过组合获得唯一的行ID,operatorid|opcode|bookkeeping_date
  • ROW_NUMBER 不是一个选项,因为由于 select 语句中的聚合函数必须对 select 语句进行分组。 ://
  • 应该提到小费和现金金额已汇总。
  • 想要的答案是什么。我认为这是不可能的,因为表格没有自然顺序。

标签: sql sql-server tsql merge composite-primary-key


【解决方案1】:

我确信这些表中的数据会定期更改,并且由于总是会引入历史记录而导致任何排名或行号功能失效,因此最好采用使用 operatorid 和 bookkeeping_date 的路线以创建一个唯一的密钥。

一种简单的方法是将日期转换为整数值,并将 operatorid 附加到末尾。

2018 年 1 月 1 日变为“43099”。 Operatorid 1 在末尾变为“1”(如果这些 ID 有可能变为更大的整数,则为“01”/“001”/“0001”)。

select
convert(int, convert(varchar(6), convert(int, (convert(datetime,replace(bookkeeping_date,'.','-'),110)))) 
    + convert(varchar(2), operatorid)) as unique_id
from (select 1 as operatorid, 1 as opcode, '01.01.2018' as bookkeeping_date, 3.50 as tip_amount) tip

在日期整数达到六位数字之前您需要几个世纪,这可能会导致一些复杂情况 - 但您也可以将日期整数转换为尾随零的东西,以适应这种情况。

【讨论】:

  • 我也考虑过这种方法,但我有点担心唯一性和整数范围。 ://
  • 如果你使用 bigint 而不是 int,你会有更多可用的值。另外,一个有趣的巧合 - 日期整数在 2173 年的这个日期(10 月 16 日)达到六位数。如果您的代码在那之后仍然运行,我推荐另一种方法。
猜你喜欢
  • 2011-10-11
  • 2017-09-26
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多