Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. MySQL на примерах. Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум MySQL

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Отбор с учетом рейтинга
 
 автор: Владимир55   (01.06.2013 в 23:52)   письмо автору
 
 

В таблице имеется поле cena для указания цены, поле artikul_kod для указания артикула, и поле metka, в котором присутствует одна их трех меток - "1С", "Ст" или "Дт". При этом с одним артикулом может только одна строка, а может быть две или три строки, отличающиеся полем metka.

Требуется отобрать товары по одному с каждым артикулом, отсортировав их по цене.

При этом, если с данным артикулом имеются три записи, то отбирается запись с меткой «1С».

Если с данным артикулом имеются две записи, одна из которых имеет метку «1С», то отбирается запись с меткой «1С».

Если имеются две записи, в одной из которых метка «Ст», а в другой метка «Дт», то отбирается запись с меткой «Ст».

Если с данным артикулом имеется только одна запись, то она и отбирается независимо от метки.

Можно ли построить такой запрос на базе SELECT или придется перебирать таблицу и удалять конкурентов для товаров с одинаковым артикулом?

  Ответить  
 
 автор: cheops   (02.06.2013 в 19:02)   письмо автору
 
   для: Владимир55   (01.06.2013 в 23:52)
 

Вы это хотите одним запросом сделать? Или можно осуществить выборку несколькими запросами, как вариант объединив их UNION (впрочем последний вариант не очень хорош, так как сортировка таких таблиц осуществляется в файле на диске).

  Ответить  
 
 автор: Владимир55   (03.06.2013 в 00:37)   письмо автору
 
   для: cheops   (02.06.2013 в 19:02)
 

Понятно, спасибо!

  Ответить  
 
 автор: Sfinks   (03.06.2013 в 11:11)   письмо автору
 
   для: Владимир55   (01.06.2013 в 23:52)
 

Надеюсь тут не TEMPORARY table ?

Как Вам такое решение?
SELECT a.*
     , case when c=1 
            or ( has_1c and metka='1С' ) 
            or ( c=2 and has_1c-1 and metka='Ст' ) then 1 end use_this 
FROM artikul_test a
JOIN( SELECT artikul 
           , count(*)c 
           , min(metka)='1С' has_1c 
      FROM artikul_test 
      GROUP BY artikul 
)t USING( artikul )
HAVING use_this
Пока вы посмотрите, я уже 6ой раз допиливаю и укорачиваю код =)

  Ответить  
 
 автор: Владимир55   (06.06.2013 в 15:32)   письмо автору
 
   для: Sfinks   (03.06.2013 в 11:11)
 

Спасибо!

  Ответить  
 
 автор: Sfinks   (06.06.2013 в 16:41)   письмо автору
 
   для: Sfinks   (03.06.2013 в 11:11)
 

А еще правильнее будет так:
/*<?*/
SELECT a.*
FROM artikul_test a
JOIN
SELECT artikul
           
count(*)c
           
min(metka)='1С' has_1c
      FROM artikul_test
      GROUP BY artikul
)t USINGartikul )
WHERE c=1
   
OR ( has_1c and metka='1С' )
   OR ( 
c=and has_1c-and metka='Ст' )

  Ответить  
 
 автор: Владимир55   (06.06.2013 в 16:49)   письмо автору
 
   для: Sfinks   (06.06.2013 в 16:41)
 

Спасибо!

  Ответить  
 
 автор: Sfinks   (06.06.2013 в 19:24)   письмо автору
 
   для: Sfinks   (06.06.2013 в 16:41)
 

И еще.
Если выполнить на эту таблицу
ALTER TABLE artikul_test ADD UNIQUE ( artikul, metka )
, то EXPLAIN очень значительно улучшается.
Исчезает Using join buffer, Using temporary и Using filesort, тип выборки меняется сразу в двух подзапросах на более скоростные, и общее количество строк резко сокращается.

Кстати, тип поля metka у Вас ENUM?

  Ответить  
 
 автор: Владимир55   (07.06.2013 в 10:28)   письмо автору
 
   для: Sfinks   (06.06.2013 в 19:24)
 

Для поля metka установлен тип CHAR. А про поле ENUM я даже не слышал, и в Справочнике у Симдянова его не обнаружил. Сюда оно очень подходит, спасибо!

Как я понял, это поле можно добавить к таблице, если изначально его нет
ALTER TABLE artikul_test ADD COLUMN metka ENUM('1С', 'Ст', 'Дт').


А как создать его непосредственно при создании таблицы?

  Ответить  
 
 автор: Sfinks   (07.06.2013 в 12:53)   письмо автору
 
   для: Владимир55   (07.06.2013 в 10:28)
 

CREATE TABLE `artikul_test` (`cena` int( 11 ) NOT NULL ,
`artikul` int( 11 ) NOT NULL ,
`metka` enum( '1С', 'Ст', 'Дт' ) NOT NULL 
) ENGINE = MYISAM DEFAULT CHARSET = utf8;
Как-то так.

> Сюда оно очень подходит, спасибо!
Оно ОЧЕНЬ подходит всегда, когда имеется список с ограниченным числом значений.
Не забывайте о нем.
Оно такое же быстрое, как и целочисленное, т.к. сервер с ним и работает как с именованными целыми числами.
Можете убедиться в этом, выполнив:
SELECT *, cast(metka AS unsigned)metka_numeric FROM artikul_test
и
SELECT * FROM artikul_test WHERE metka=1

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования