Reputation: 2543
I'm hacking on my Zotero database with sqlite3, since the Zotero gui still doesn't support editing multiple records at once. Current task is finding all items from a particular journal, separating out the ones that don't yet have a value for journalAbbreviation
, and adding the correct abbreviation. Here are the relevant tables:
fields (fieldID, fieldName, fieldFormatID)
itemData (itemID, fieldID, valueID)
itemDataValues (valueID, value)
Here is my query to find all the records I want:
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'));
Now that I have that list of itemID
s, I want to add a bunch of entries to the itemData
table. Schematically I want to do this:
INSERT INTO itemData (itemID, fieldID, valueID)
VALUES (A,X,Y),(B,X,Y),(C,X,Y), ... (W,X,Y);
where X is the fieldID
for 'journalAbbreviation' and Y is the valueID
for 'J. Acoust. Soc. Am.' (I know how to get those values). How can I write this INSERT INTO
statement to replace A
, B
, C
, etc with the itemID
s from my SELECT
query above?
note: some of the records already have the journal abbreviation in there. I've only been writing SQL
for a few days, so I don't know if it will cause problems to try to INSERT
a record that already exists in the table (I'm assuming it will, based on a vague understanding of primary keys and the fact that the schema section in the itemData
table includes a line PRIMARY KEY (itemID, fieldID)
). So it may be necessary to first exclude those itemID
s that already have a record in itemData
that includes X as fieldID
.
Upvotes: 1
Views: 155
Reputation: 928
You may want to do this via Zotero's javascript API, which makes data corruption a lot less likely. http://www.zotero.org/support/dev/client_coding/javascript_api
Also, if all you're looking for is journal abbreviations, consider running the branch xpi for Zotero's 3.1 branch, which has automatic journal abbreviations via a list from MEDLINE: http://www.zotero.org/support/dev_builds#zotero_31_branch
Upvotes: 1
Reputation: 9158
With little discussion with @drammock, found a query that is working. Main part of this query is EXCEPT
keyword.
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'));
Upvotes: 1
Reputation: 5791
This is basically a copy of Ravindra's answer only with DISTINCT
and my preferred syntax of having the foreign key links in the FROM
statement simplifying the WHERE
clause, and in my opinion making it more readable.
I've also added a self join and said WHERE existing.itemID IS NULL
to avoid inserting records that already exist.
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
Upvotes: 1