2009-12-04 4 views
1

Немного странно, я хочу написать запрос MySQL, который будет получать результаты из таблицы, но предпочитают одно значение столбца над другим, т.е.MySQL получить строки, но предпочитают одно значение столбца над другим

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

Итак, здесь name1 имеет две записи, но у одного есть prioirty из 1. Я хочу получить все значения из таблицы, но предпочитаю значения с любым приоритетом, которым я пользуюсь.

Результаты, которые я бы после того, как будет

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

Эквивалентный способ сказать, что это было бы «получить все строки из таблицы, но предпочитают строки с приоритетом х».

+0

Это немного недооценено.«Предпочитаете» вы имеете в виду: «если строка существует с приоритетом x, то извлекайте эту строку, иначе ... что?» «В противном случае» может быть несколько разных определений в зависимости от того, может ли быть несколько таких строк «в противном случае». Вам нужно полностью определить желаемые результаты «в противном случае». –

+0

Otheriwse возвращает другую строку с тем же именем, но с prioirty из NULL. Как минимум одна строка с именем1, name2, name3 всегда будет существовать в таблице. Бывает, что могут быть и другие версии (с тем же именем), но с разными значениями prioirty. Я пытаюсь получить то, что мне нужно, не выполняя два запроса (один для prioirty = null и один для prioirty = x), а затем сравнение двух наборов результатов. Cheers, Gaz. – Gaz

+0

Идея на это: http://stackoverflow.com/questions/1848693/mysql-get-rows-but-prefer-one-column-value-over-another – 2013-07-15 20:41:04

ответ

1

Вам необходимо перепроектировать таблицу первой.

Оно должно быть:

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

Update:

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

Это должно работать в SQL Server, вы, возможно, потребуется немного изменить, чтобы заставить его работать в MySQL.

+0

В чем смысл? И какая разница в душе? – Gaz

+1

Ваша таблица будет нормализована и не будет значений NULL – Tebo

+0

Он также удалит дублирующее имя1 и значение1 – Tebo

0

Может быть что-то вроде:

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

Хотя не имея базу данных передо мной, я не могу проверить это ...

2

Это следует сделать это:

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 

Это также позволяет иметь несколько уровней приоритета с высоким будучи тот, который вы хотите вернуть (если у вас есть 1 и 2, то 2 будет возвращен).

Я также скажу, что, похоже, в БД есть некоторые проблемы с дизайном. Мой подход был бы:

My_Table (id, name) My_Values ​​(id, priority, value) с идентификатором FK от id до id. PKs на id в My_Table и id, приоритет в My_Values. Конечно, я бы тоже использовал соответствующие имена таблиц.

+0

@Tom, когда я запускаю это в наборе данных Gary, я получаю результаты только для «name2» и «name3» - интересный случай исключается, потому что предложение WHERE является ложным везде, где T2.priority фактически определен ... – pilcrow

+0

Упс ...>> должен быть>. Я исправлю это. –

0

Если я правильно понимаю, вы хотите value из name дан конкретныхpriority, или value, связанный с NULL priority. (Вам необязательно нужен существующий MAX(priority)).

Да, у вас есть некоторые неудобные проблемы с дизайном, к которым вы должны обратиться, но давайте решим проблему, которая у вас есть на данный момент (и вы можете позже перейти к проблеме вы должны иметь :)):

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) 

(Обратите внимание, что я изменил приоритетный value «NAME1» в «valueX» в приведенном выше - исходной композиции имели одинаковые value значения «имя1» независимо от приоритета , из-за чего мне было трудно понять, почему вы должны различать один от другого.)

Смежные вопросы