如何使用`select`的结果作为`insert into`的参数

时间:2013-03-04 18:36:35

标签: sql select sqlite bulkinsert

我正在使用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'));

现在我有了itemID的列表,我想在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。声量。 SOC。上午。' (我知道如何获得这些价值观)。如何使用上面INSERT INTO查询中的A来编写此B语句以替换CitemIDSELECT等?

注意:某些记录中已有日记缩写。我只写了SQL几天,所以我不知道是否会导致问题尝试INSERT表中已经存在的记录(我假设它会,基于对主键的模糊理解以及itemData表中的模式部分包含行PRIMARY KEY (itemID, fieldID)的事实。因此,可能有必要首先将itemID中已包含X的记录itemData排除在fieldID之外。

3 个答案:

答案 0 :(得分: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'));

答案 1 :(得分:1)

这基本上只是使用DISTINCT的Ravindra答案的副本,以及我在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

答案 2 :(得分:1)

您可能希望通过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