【问题标题】:How to insert a column which sets unique id based on values in another column (SQL)?如何插入根据另一列(SQL)中的值设置唯一ID的列?
【发布时间】:2025-12-25 08:40:11
【问题描述】:

我将创建一个表,我将在其中为不同的公司插入多个值。基本上我有下表中的所有值,但我想添加一个链接到IndicatorName 的列IndicatorID,以便每个指标都有一个唯一的ID。这显然不是PrimaryKey

我将通过多选插入数据:

CREATE TABLE abc                
INSERT INTO abc
SELECT company_id, 'roe', roevalue, metricdate
FROM TABLE1 
INSERT INTO abc
SELECT company_id, 'd/e', devalue, metricdate
FROM TABLE1

所以,我不知道如何添加我上面提到的IndicatorID。

编辑: 以下是我填充新表的方式:

INSERT INTO table(IndicatorID, Indicator, Company, Value, Date)

SELECT [the ID that I need], 'NI_3y' as 'Indicator', t.Company, avg(t.ni) over (partition by t.Company order by t.reportdate rows between 2 preceding and current row) as 'ni_3y',
t.reportdate
FROM table t
LEFT JOIN IndicatorIDs i
ON i.Indicator = roe3 -- the part that is not working if I have separate indicatorID table

我将为同一家公司插入不同的指标。我想要indicatorID。

【问题讨论】:

    标签: sql tsql sql-insert create-table


    【解决方案1】:

    您的“指标”本身就是一个适当的实体。创建一个包含所有指标的表格:

    create table indicators (
        indicator_id int identity(1, 1) primary key,
        indicator varchar(255)
    );
    

    然后,在此表中使用id only。您可以在参考表中查找该值。

    你的插入会稍微复杂一点:

    INSERT INTO indicators (indicator)
        SELECT DISTINCT roevalue
        FROM table1 t1
        WHERE NOT EXISTS (SELECT 1 FROM indicators i2 WHERE i2.indicator = t1.roevalue);
    

    然后:

    INSERT INTO ABC (indicatorId, companyid, value, date)
        SELECT i.indicatorId, t1.company, v.value, t1.metricdate
        FROM table1 t1 CROSS APPLY
             (VALUES ('roe', t1.roevalue), ('d/e', t1.devalue)
             ) v(indicator, value) JOIN
             indicators i
             ON i.indicator = v.indicator;
    

    这个过程称为规范化,它是在数据库中存储数据的典型方式。

    【讨论】:

    • 但指标不是我表中存在的列。我将它创建为“NI”作为“指标”,所以我不能使用交叉应用。
    • @Yana 。 . .嗯? CROSS APPLY 生成指标值。
    • 我编辑了我对问题的描述。希望它不会引起进一步的混乱
    【解决方案2】:

    DDL 和 INSERT 语句创建一个对指标具有唯一约束的指标表。因为 ind_id 旨在作为 abc 表中的外键,所以它使用 IDENTITY 属性创建为不可分解的代理整数主键。

    drop table if exists test_indicators;
    go
    create table test_indicators (
      ind_id        int identity(1, 1) primary key not null,
      indicator     varchar(20) unique not null);
    go
    
    insert into test_indicators(indicator) values
    ('NI'),
    ('ROE'),
    ('D/E');
    

    abc 表依赖于指标表中的 ind_id 列作为外键引用。填充 abc 表 company_id's 与 ind_id's 相关联。

    drop table if exists test_abc
    go
    create table test_abc(
      a_id  int     identity(1, 1) primary key not null,
      ind_id        int not null references test_indicators(ind_id),
      company_id    int not null,
      val           varchar(20) null);
    go
    
    insert into test_abc(ind_id, company_id) 
    select ind_id, 102 from test_indicators where indicator='NI'
    union all
    select ind_id, 103 from test_indicators where indicator='ROE'
    union all
    select ind_id, 104 from test_indicators where indicator='D/E'
    union all
    select ind_id, 103 from test_indicators where indicator='NI'
    union all
    select ind_id, 105 from test_indicators where indicator='ROE'
    union all
    select ind_id, 102 from test_indicators where indicator='NI';
    

    查询得到结果

    select i.ind_id, a.company_id, i.indicator, a.val
    from test_abc a
         join test_indicators i on a.ind_id=i.ind_id;
    

    输出

    ind_id  company_id  indicator   val
    1       102         NI          NULL
    2       103         ROE         NULL
    3       104         D/E         NULL
    1       103         NI          NULL
    2       105         ROE         NULL
    1       102         NI          NULL
    

    【讨论】:

      【解决方案3】:

      我终于能够找到解决我的问题的方法,这在我看来非常简单,尽管这需要时间并询问不同的人。 首先,我创建我的indicators 表,在其中为我拥有的所有指标分配primary key

      CREATE TABLE indicators (
          indicator_id int identity(1, 1) primary key,
          indicator varchar(255)
      );
      

      然后我无需使用任何JOINsCROSS APPLY 即可轻松填充。我不知道这是否是最佳选择,但它似乎是最简单的选择:

      INSERT INTO table(IndicatorID, Indicator, Company, Value, Date)    
      SELECT 
          (SELECT indicator_id from indicators i where i.indicator = 'NI_3y) as IndicatorID, 
          'NI_3y' as 'Indicator', 
           Company, 
           avg(ni) over (partition by Company order by reportdate rows between 2 preceding and current row) as ni_3y,
          reportdate
      FROM TABLE1
      

      【讨论】:

        最近更新 更多