简体   繁体   English

根据列值在 sql 表中插入行

[英]Insert row inside sql table based on its column value

i am having table file which contains multiple columns, one of them is val which was combination of 3 attributes version,name and availability all three are combined with ;我有一个包含多个列的表格file ,其中之一是val ,它是 3 个属性version,name and availability的组合,这三个属性都与; and stored inside val .并存储在val中。 Now i have to insert 3 rows with coping all data and value ie现在我必须插入3 rows来处理所有数据和值,即

id    file_id   file_version_id   val                  type

162   190234       259           1.2;DESC;AVAIL        desc
============================================================

id   file_id   file_version_id      val                type
162   190234       259             1.2                version

id   file_id   file_version_id      val                type
162   190234       259             DESC                name

 id   file_id   file_version_id     val                 type
162   190234       259              AVAIL           availability

As you can see from the example, i have to insert 3 records with its data from parent row.从示例中可以看出,我必须从父行插入3 records及其数据。 The order of data is version,name and availability in case for some records name is not available ie 3.4;NOT_AVAIL then have to insert only two records with type Version and availability数据的顺序是version,name and availability ,以防某些记录name不可用,即3.4;NOT_AVAIL然后只需要插入两个类型为Versionavailability的记录

You can use UNNEST() to split the column val and a CASE expression to update the column type :您可以使用UNNEST()拆分列val和 CASE 表达式来更新列type

INSERT INTO tablename (id, file_id, file_version_id, val, type)
WITH cte AS (
  SELECT *, UNNEST(STRING_TO_ARRAY(val, ';')) str
  FROM tablename                              
)
SELECT id, file_id, file_version_id, str,
  CASE
    WHEN str ~ '^[0-9\.]+$' THEN 'version'
    WHEN str IN ('AVAIL', 'NOT AVAIL') THEN 'availability'
    ELSE 'name'                   
  END
FROM cte;

See a simplified demo .查看简化的演示

Presumably, it is the positions of the values in the string that determine the type , not their values.大概是字符串中值的位置决定了type ,而不是它们的值。 I would suggest unnest() with the position and a case expression:我建议unnest()使用 position 和一个case表达式:

insert into file (id, file_id, file_version_id, val, type)
    select f.id, f.file_id, f.file_version_id, u.val,
           (case u.n 
                when 1 then 'version'
                when 2 then 'name'
                when 3 then 'availability'
            end)
    from file f cross join lateral
         unnest(string_to_array(f.val, ';')) with ordinality u(val, n);

If you want to be sure that all values are present, you might want where f.val like '%;%;%' .如果您想确保所有值都存在,您可能需要where f.val like '%;%;%'

Here is a db<>fiddle. 是一个 db<>fiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM