1

My situation is as follows (SQLfiddle):

I have two tables People and Scores and they look like this:

CREATE TABLE People 
(
    name TEXT,
    minScore INTEGER,
    maxScore INTEGER,
    FOREIGN KEY (minScore) REFERENCES B(rowid),
    FOREIGN KEY (maxScore) REFERENCES B(rowid)
);

INSERT INTO People (name) VALUES ('Terry');
INSERT INTO People (name) VALUES ('Bob');

CREATE TABLE Scores  
(
    nameID INTEGER,
    score INTEGER,
    FOREIGN KEY (nameID) REFERENCES A(rowid)
);

INSERT INTO Scores (nameID, score) VALUES (1, 10);
INSERT INTO Scores (nameID, score) VALUES (1, 8);
INSERT INTO Scores (nameID, score) VALUES (1, 5);
INSERT INTO Scores (nameID, score) VALUES (2, 12);
INSERT INTO Scores (nameID, score) VALUES (2, 8);
INSERT INTO Scores (nameID, score) VALUES (2, 2);

I want to update the People table to contain the rowID of their minScore and maxScore. How do I do that?

AIM:

Terry | 5 | 10
Bob   | 2 | 12

This is what I have tried:

CREATE VIEW minScores 
AS 
    SELECT Scores.rowid AS scoreID, Scores.nameID AS nameID 
    FROM Scores 
    WHERE score IN (SELECT MIN(score) 
                    FROM Scores AS Scores2 
                    GROUP BY Scores2.nameID);

UPDATE People
SET minScore = (SELECT scoreID FROM minScores) 
WHERE People.rowid IN (SELECT nameID FROM minScores)

Which just populates the table with the last minimum value.

(I had to use a view because I couldn't get USING to work...)

1
  • Thank you for the edit @CL. That reads much better. Commented May 25, 2017 at 7:27

1 Answer 1

2

Your update uses a scalar subquery; its value

is the first row of the result from the enclosed SELECT statement. In other words, an implied "LIMIT 1" is added to the subquery.

To get different results for different rows, you have to use a correlated subquery:

UPDATE People
SET minScore = (SELECT rowid
                FROM Scores
                WHERE Scores.nameID = People.rowid
                ORDER BY score ASC),
    maxScore = (SELECT rowid
                FROM Scores
                WHERE Scores.nameID = People.rowid
                ORDER BY score DESC);

(And you should not use the implicit rowid for foreign keys; its value can change.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @CL. I'll study that a bit more on the train this morning. I didn't know about not using rowid, I was taught that it's better than creating an ID key, but I presume my lecturer wasn't aware that it could change (unless I got the wrong end of the stick).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.