Question

Okay so I am trying to get some ideas on how to go about determining the top choices of camera I have from the table setup below. This is not a real scenario I am just trying to figure out the best way or some way to go about doing this.

So the camera table has entries id(INT) which is unique, name(VARCHAR), reviewRank(INT), price(INT), and failRate(INT). Here is an example of the TABLE setup and inserts code:

CREATE TABLE CAMERA(
id INTEGER,
name VARCHAR(30),
reviewRank INT,
price INT,
failRate INT,
PRIMARY KEY(id))ENGINE=INNODB;

INSERT INTO CAMERA VALUES(1,'Camera 1',5,100,1);
INSERT INTO CAMERA VALUES(2,'Camera 2',4,300,7);
INSERT INTO CAMERA VALUES(3,'Camera 3',1,10,99);
INSERT INTO CAMERA VALUES(4,'Camera 4',1,10,6);

Criteria is that a higher reviewRank is better, a lower price is better, and a lower failRate is better. And if multiple cameras share the best value for one of the columns then we choose the one with the best values in the other two columns or if multiple cameras have the same values in multiple columns such as CAMERA(3,'Camera 3',1,10,99) and CAMERA(4,'Camera 4',1,10,6) do then the last column determines the outcome.

Basically any camera with the best value in any of the three columns automatically becomes a candidate for the list of top cameras to choose from. But if multiple cameras have the best value for the same column then we need to determine which is the best of these by looking at the values of the other columns.

So using the database state above the query would return cameras (1,'Camera 1',5,100,1) and (4,'Camera 4',1,10,6) since camera id 1 has the highest reviewRank and lowest failRate and camera id 4 and camera id 3 tie for having the lowest price but camera id 4 has a lower failRate than camera id 3.

So basically I am trying to figure a way to go about finding the top choices where there are multiple column comparisons using MySQL preferably using a single query if possible.

My initial thoughts were something like this

SELECT DISTINCT C.* 
FROM CAMERA C
WHERE C.reviewRank>=ALL(SELECT reviewRank FROM CAMERA)
OR    C.price<=ALL(SELECT price FROM CAMERA)
OR    C.failRate<=ALL(SELECT failRate FROM CAMERA);

However this is obviously wrong since it does not cover all of the possible permutations. And after doing quite a bit of searching for a way to go about this I still have no idea how to go about this.

Was it helpful?

Solution

I believe that the ORDER BY clause accomplishes what you're looking for:

SELECT topC.Id, topC.Name, topC.ReviewRank, topC.Price, topC.FailRate
FROM Camera topC JOIN (
    (SELECT c.ReviewRank, c.Price, c.FailRate
    FROM Camera c
    ORDER BY 
        c.ReviewRank DESC,
        c.Price,
        c.FailRate
    LIMIT 1)
    UNION 
    (SELECT c.ReviewRank, c.Price, c.FailRate
    FROM Camera c
    ORDER BY 
        c.Price,
        c.FailRate,
        c.ReviewRank DESC
    LIMIT 1)
    UNION 
    (SELECT c.ReviewRank, c.Price, c.FailRate
    FROM Camera c
    ORDER BY 
        c.FailRate,
        c.Price,
        c.ReviewRank DESC
    LIMIT 1)
) values 
    ON values.ReviewRank = topC.ReviewRank
    AND values.Price = topC.price
    AND values.FailRate = topC.FailRate
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top