开发者

MySQL get rows but prefer one column value over another

A bit of a strange one, I want to write a MySQL query that will get results from a table, but prefer one value of a column over another, ie

id   name    value   prioirty
1    name1   value1  NULL
2    name1   value1  1
3    name2   value2  NULL
4    name3   value3  NULL

So here name1 has two entries, but one has a prioirty of 1. I want to get all the values from the table, but prefer the values with whatever priorty I'm after.

The results I'd be after would be

id   name    value   prioirty
开发者_如何学C2    name1   value1  1
3    name2   value2  NULL
4    name3   value3  NULL

An equivalent way of saying it would be 'get all rows from the table, but prefer rows with a priority of x'.


This should do it:

SELECT
     T1.id,
     T1.name,
     T1.value,
     T1.priority
FROM
     My_Table T1
LEFT OUTER JOIN My_Table T2 ON
     T2.name = T1.name AND
     T2.priority > COALESCE(T1.priority, -1)
WHERE
     T2.id IS NULL

This also allows you to have multiple priority levels with the highest being the one that you want to return (if you had a 1 and 2, the 2 would be returned).

I will also say though that it does seem like there are some design problems in the DB. My approach would have been:

My_Table (id, name) My_Values (id, priority, value) with an FK on id to id. PKs on id in My_Table and id, priority in My_Values. Of course, I'd use appropriate table names too.


You need to redesign your table first.

It should be:

YourTable (Id, Name, Value)
YourTablePriority (PriorityId, Priority, Id)

Update:

select * from YourTable a 
where a.Id not in 
   (select b.Id from YourTablePriority b)

This should work in sql server, you may need a little change to make it work in mysql.


Maybe something like:

SELECT id, name, value, priority FROM 
table_name GROUP BY name ORDER BY priority

Although not having a database in front of me I can't test it...


If I understand correctly, you want the value of a name given a specific priority, or the value associated with a NULL priority. (You do not necessarily want the MAX(priority) that exists.)

Yes, you've got some awkward design issues which you should address, but let's solve the problem you do have at present (and you can later migrate to the problem you ought to have :) ):

mysql> SET @priority = 1;  -- the priority we want, if recorded

mysql> PREPARE stmt FROM "
       SELECT
         t0.*
       FROM
         t t0
       LEFT JOIN
         (SELECT DISTINCT name, priority FROM t WHERE priority = ?) t1
           ON t0.name = t1.name
       WHERE
         t0.priority = t1.priority
           OR
         t1.priority IS NULL
       ";

mysql> EXECUTE stmt USING @priority;
+----+-------+--------+----------+
| id | name  | value  | priority |
+----+-------+--------+----------+
|  2 | name1 | valueX |        1 | 
|  3 | name2 | value2 |     NULL | 
|  4 | name3 | value3 |     NULL | 
+----+-------+--------+----------+
3 rows in set (0.00 sec)

(Note that I changed the prioritized value of "name1" to "valueX" in the above -- your original formulation had identical value values for "name1" regardless of priority, which made it hard for me to understand why you cared to discriminate one from the other.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜