【问题标题】:how to use results of `select` as argument to `insert into`如何使用`select`的结果作为`insert into`的参数
【发布时间】:2013-03-04 18:36:35
【问题描述】:

我正在使用 sqlite3 破解我的 Zotero 数据库,因为 Zotero gui 仍然不支持一次编辑多条记录。当前任务是查找特定期刊中的所有项目,分离出尚无journalAbbreviation 值的项目,并添加正确的缩写。以下是相关表格:

fields (fieldID, fieldName, fieldFormatID)
itemData (itemID, fieldID, valueID)
itemDataValues (valueID, value)

这是我的查询,用于查找我想要的所有记录:

SELECT itemData.itemID
FROM fields JOIN itemData JOIN itemDataValues 
WHERE (fields.fieldname IN ('publicationTitle'))  
AND (fields.fieldID = itemData.fieldID) 
AND (itemData.valueID = itemDataValues.valueID) 
AND (itemDataValues.value IN ('The Journal of the Acoustical Society of America'));

现在我有了itemIDs 的列表,我想将一堆条目添加到itemData 表中。理论上我想这样做:

INSERT INTO itemData (itemID, fieldID, valueID)
VALUES (A,X,Y),(B,X,Y),(C,X,Y), ... (W,X,Y);

其中 X 是“journalAbbreviation”的fieldID,Y 是“J”的valueID。声学。社会党。是。' (我知道如何获得这些值)。如何编写此 INSERT INTO 语句以将 ABC 等替换为我上面的 SELECT 查询中的 itemIDs?

注意:有些记录中已经有期刊缩写。我才写SQL 几天,所以我不知道尝试INSERT 表中已经存在的记录是否会导致问题(我假设它会,基于对主键的模糊理解以及itemData 表中的架构部分包含一行PRIMARY KEY (itemID, fieldID) 的事实。所以可能需要先排除那些在itemData中已经有记录的itemIDs,其中包含X为fieldID

【问题讨论】:

  • ...你试过用谷歌搜索你的问题吗? msdn.microsoft.com/en-us/library/ms188263%28v=sql.105%29.aspxstackoverflow.com/questions/25969/… 这是非常基本的语法,只要你知道它就在那里。
  • @Syn123:我以为它就在那里,然后我用谷歌搜索。作为一个新的 SQL 编写者,我显然没有找到正确的搜索词,或者当我看到它时没有识别出正确的答案。我发现的所有内容似乎都意味着您必须分别写出INSERT INTO ... VALUES(),(),(); 语句的每条记录,这似乎效率低得可笑。所以我寻求帮助。
  • 如果有帮助,我用谷歌搜索找到上述链接是:“SQL INSERT INTO SELECT”。我以类似的方式搜索了大多数与 SQL 相关的东西,因为 SQL 是一种如此流行的技术。

标签: sql select sqlite bulkinsert


【解决方案1】:

几乎没有与@drammock 讨论,发现一个有效的查询。此查询的主要部分是EXCEPT 关键字。

INSERT INTO itemData (itemID, fieldID, valueID) 
SELECT itemData.itemID, 25, 8356
FROM fields JOIN itemData JOIN itemDataValues 
WHERE (fields.fieldname IN ('publicationTitle'))  
AND (fields.fieldID = itemData.fieldID) 
AND (itemData.valueID = itemDataValues.valueID) 
AND (itemDataValues.value IN ('The Journal of the Acoustical Society of America'))
EXCEPT SELECT itemData.itemID, 25, 8356
FROM fields JOIN itemData JOIN itemDataValues 
WHERE (fields.fieldname IN ('journalAbbreviation'))  
AND (fields.fieldID = itemData.fieldID) 
AND (itemData.valueID = itemDataValues.valueID) 
AND (itemDataValues.value IN ('J. Acoust. Soc. Am.', 'J Acoust Soc Am'));

【讨论】:

  • 使用 DISTINCT 关键字或 INNER JOIN 来获取不同的值集。检查更新的查询。
  • 解释性说明:25 是“journalAbbreviation”的fieldID,8356 是“J. Acoust. Soc. Am.”的valueID
【解决方案2】:

这基本上是 Ravindra 答案的副本,仅包含 DISTINCT 和我的首选语法,即在 FROM 语句中使用外键链接简化了 WHERE 子句,并在我看来使其更具可读性。

我还添加了一个自连接并说WHERE existing.itemID IS NULL 以避免插入已经存在的记录。

INSERT INTO itemData (
  itemID, 
  fieldID, 
  valueID) 
SELECT DISTINCT
  itemData.itemID, 
  'journalAbbreviation', 
  'Journal of the Acoustical Society of America' 
FROM 
  fields 
    INNER JOIN itemData ON fields.fieldID = itemData.fieldID
    INNER JOIN itemDataValues ON itemData.valueID = itemDataValues.valueID
    LEFT OUTER JOIN itemData existing ON itemData.itemID = existing.itemID
WHERE 
  fields.fieldname = 'publicationTitle'
  AND itemDataValues.value = 'The Journal of the Acoustical Society of America'
  AND existing.itemID IS NULL

【讨论】:

    【解决方案3】:

    您可能希望通过 Zotero 的 javascript API 来执行此操作,这使得数据损坏的可能性大大降低。 http://www.zotero.org/support/dev/client_coding/javascript_api

    另外,如果您要查找的只是期刊缩写,请考虑为 Zotero 的 3.1 分支运行 xpi 分支,该分支通过 MEDLINE 的列表具有自动期刊缩写: http://www.zotero.org/support/dev_builds#zotero_31_branch

    【讨论】:

    • 我考虑过使用API​​,但我不太了解Javascript。很高兴知道缩写正在自动添加。
    猜你喜欢
    • 2021-07-22
    • 2012-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-23
    • 1970-01-01
    • 2013-06-21
    相关资源
    最近更新 更多