2013-03-27 2 views
1

Для краткости позволяет сказать, у меня есть таблица, которая выглядит следующим образом:Выбрать без дубликата

item_name item_location item_price 
PROMO_A  local   5 
B   local   7 
PROMO_A  global   8 

Теперь, что я делаю, я выбрать все записи, в которых item_location является «местным» или где item_name содержит слово PROMO, но item_location не является «местным». Это, на мой SQL запрос выглядит просто:

SELECT * FROM mytable WHERE item_location='local' OR (item_name like 'PROMO%' AND item_location != 'local'); 

Теперь, это может произойти, как в примере данных я настроил выше, что я хотел бы получить два одинаковых item_name «s, так что я задаюсь вопросом, как я мог исправить этот запрос, чтобы последний не был добавлен? Я могу исправить это, написав PHP-программу, которая будет проходить через записи и удалять дубликаты (мне нужно удалить дубликаты (те, у которых одинаковое имя_пользователя), которые имеют item_location == 'global'), но мне было интересно, может ли это быть выполняется только с помощью SQL? Я думал создать временную таблицу из вышеуказанного запроса, а затем запросить отдельные записи item_name, но как же тогда я в этом случае удалю те, у которых item_location «global»?

В любом случае, любая помощь приветствуется.

Редактировать: Я создал SQL Fiddle link for this.

edit2: Мне удалось получить эту работу с помощью следующего запроса:

SELECT * FROM туЬаЫе WHERE item_location = 'местный'

UNION

SELECT * FROM туЬаЫе ГДЕ item_name LIKE 'PROMO%' AND item_name NOT IN
(SELECT item_name from mytable WHERE item_location = 'local')

И ссылка для скрипта sql для этого является here.

Теперь я считаю, что это можно было бы обработать лучше, поэтому, если у кого-то есть лучшие подходы, я хотел бы услышать ваши мысли.

+0

Вы пытались использовать DISTINCT или поля? –

ответ

1

Ваш UNION запрос может быть упрощен до

SELECT * FROM mytable 
WHERE item_location = 'local' 
OR item_name LIKE 'PROMO%' AND item_name NOT IN 
    (SELECT item_name FROM mytable 
    WHERE item_location = 'local') 

другой запрос, который дает тот же результат, используя LEFT JOIN вместо подзапроса является

SELECT mt.* FROM mytable AS mt 
LEFT JOIN mytable as mt2 
ON mt2.item_name = mt.item_name  -- check for similar items 
AND mt2.item_location = 'local'  -- whose location is 'local' 
WHERE mt.item_location = 'local' 
OR mt.item_name LIKE 'PROMO%' 
AND mt2.item_location IS NULL;  -- only include if not found locally 
+0

Thx, этот запрос работает, и вы видите, что он «лучше» с точки зрения скорости? Как я понял, легче понять. Является ли использование UNION не предложенным из-за производительности или некоторых других проблем? – Nikola

+0

Теперь я добавил упрощенную версию запроса 'UNION', который, вероятно, более эффективен, чем оригинал, но не может сказать, как он будет сравниваться с запросом с помощью' LEFT JOIN' вместо подзапроса. Если производительность является проблемой, вы должны проверить оба запроса. –

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