【问题标题】:How to add data to a field based on other fields in a SQL database如何根据 SQL 数据库中的其他字段向字段添加数据
【发布时间】:2021-11-01 01:42:33
【问题描述】:

我有一个名为 wcvp 的 SQLite 表,它是根据从世界维管植物清单下载的 csv 文件构建的(请参阅 https://wcvp.science.kew.org/http://sftp.kew.org/pub/data-repositories/WCVP/)。当我运行这个查询时:

sqlite> SELECT kew_id, genus, species, infraspecies 
        FROM wcvp 
        WHERE genus = 'Quercus' 
          AND species = 'robur' 
          AND taxonomic_status = 'Accepted';

我得到这个结果:

kew_id genus species infraspecies
304293-2 Quercus robur
77189540-1 Quercus robur broteroana
77189379-1 Quercus robur brutia
77189383-1 Quercus robur imeretina
60459295-2 Quercus robur pedunculiflo
77171868-1 Quercus robur robur

我想向表(其中包含数十万行)添加一个名为 number_of_infraspecies 的列,如下所示:

kew_id genus species infraspecies number_of_infraspecies
304293-2 Quercus robur 5
77189540-1 Quercus robur broteroana NULL
77189379-1 Quercus robur brutia NULL
77189383-1 Quercus robur imeretina NULL
60459295-2 Quercus robur pedunculiflo NULL
77171868-1 Quercus robur robur NULL

或者,我可以构建一个包含两列的新表:kew_id 作为外键,number_of_infraspecies 作为另一列。

无论我采用哪种方法,我只能想到一个过程,该过程会导致对wcvp 表的每一行或至少那些在 infraspecies 列中没有值的行进行单独查询(AND taxonomic_status = '接受')。

有没有办法通过一个或几个查询来做到这一点?

【问题讨论】:

  • 您是否想过如果在表格中为新工厂添加新行或删除行会发生什么?您将不得不更新该号码。还是静态表?
  • 我没有想过这一点,尽管我认为我可以让它保持静态。每次 WCVP 发布我认为每周更新的数据库版本时,我都需要能够再次生成它。除了在代码逻辑中不改变静态表之外,还有什么正式的方法可以创建和处理静态表?
  • 我已经发布了一个我建议使用 VIEW 的答案。你可以检查一下。
  • 我很惊讶用这么少的代码就可以完成!有一个解决方案来努力理解是件好事,因为我发现定向学习比一般地尝试更好地学习 SQL 更好(尽管我也应该做更多的事情)。

标签: sql sqlite view count window-functions


【解决方案1】:

创建一个返回number_of_infraspecies 列的VIEW

CREATE VIEW my_view AS
SELECT kew_id, genus, species, infraspecies,
       CASE 
         WHEN infraspecies IS NULL 
           THEN COUNT(infraspecies) OVER (PARTITION BY genus, species)
       END number_of_infraspecies
FROM wcvp
WHERE taxonomic_status = 'Accepted';

然后从VIEW 特定的genusspecies 中选择:

SELECT kew_id, genus, species, infraspecies, number_of_infraspecies
FROM my_view
WHERE genus = 'Quercus' AND species = 'robur';

请参阅demo

【讨论】:

    【解决方案2】:

    我想你只是想将count(*) 作为一个窗口函数:

    SELECT kew_id, genus, species, infraspecies,
           COUNT(*) OVER (PARTITION BY genus, species) as infra_species
    FROM wcvp
    WHERE genus = 'Quercus' AND species = 'robur' AND
          taxonomic_status = 'Accepted';
    

    【讨论】:

    • 谢谢!我会调查这个以及@forpas 的答案。
    猜你喜欢
    • 1970-01-01
    • 2020-09-29
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-11
    相关资源
    最近更新 更多