|
|
|
Выборка лучшего значения по двум параметрам
|
|||
|---|---|---|---|
|
#18+
Всем привет! Есть такая табличка: `trunk` varchar(24) NOT NULL, `destination` varchar(64) DEFAULT NULL, `prefix` bigint(15) NOT NULL, `price` decimal(5,5) NOT NULL В ней лежат значения прайсов в виде имя провайдера- описание маршрута- префикс - цена. Ну например для номера МТС: MariaDB [price_comparison]> select * from price WHERE ( 791878500000 like concat (prefix,'%')) order by length(prefix); +------------+------------------------------+--------+---------+ | trunk | destination | prefix | price | +------------+------------------------------+--------+---------+ | ringtime | Russian FederationLandline | 7 | 0.19000 | | siptraffic | Russia - Fixed | 7 | 0.02090 | | bestvoip | RussianFederationFIX | 7 | 0.02500 | | ringtime | Russian FederationMobile | 79 | 0.23200 | | bestvoip | RussianFederationMOB | 79 | 0.09000 | | ringtime | Russian FederationMTS Mobile | 791 | 0.19200 | | siptraffic | Russia Mobile MTS | 791 | 0.05460 | +------------+------------------------------+--------+---------+ Суть простая- нужно чтобы запрос выгребал лучшее значение цены, выбирая при этом у каждого оператора максимально совпадающий префикс и из этих результатов ( по одному от каждого оператора) выбрать тот, который с наименьшей ценой. Сложность в том что у каждого оператора разное количество префиксов, префиксы разной длины и тупо отсортировать по длине префикса не получится. Подскажите. пожалуйста, какие есть варианты? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2016, 13:15 |
|
||
|
Выборка лучшего значения по двум параметрам
|
|||
|---|---|---|---|
|
#18+
At6нужно чтобы запрос выгребал лучшее значение цены, выбирая при этом у каждого оператора максимально совпадающий префикс и из этих результатов ( по одному от каждого оператора) выбрать тот, который с наименьшей ценой.А вот теперь объясни, зачем сначала надо что-то отбирать по оператору? что мешает сразу свалить всё в кучу и выбрать наименьшее, не обращая внимания на оператора? Результат-то будет такой же... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2016, 18:44 |
|
||
|
Выборка лучшего значения по двум параметрам
|
|||
|---|---|---|---|
|
#18+
Akina, не все так просто. К примеру, в выхлопе выше Код: plsql 1. 2. оператор реально применит второй ( то бишь тот где префикс длиннее по совпадению с номером). И потому нужно сначала выбрать у каждого оператора один префикс, который реально применяем к номеру при обсчете, и только потом смотрим кого из операторов он дешевле. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2016, 19:57 |
|
||
|
Выборка лучшего значения по двум параметрам
|
|||
|---|---|---|---|
|
#18+
At6нужно сначала выбрать у каждого оператора один префикс, который реально применяем к номеру при обсчете, и только потом смотрим кого из операторов он дешевле. Вот если бы ты делал это в процедурном языке, то у тебя было бы право и рассуждать так, и делать так - сперва один критерий, затем к тому, что просочилось, второй... Но ты имеешь дело с SQL-сервером, который работает совершенно иначе - сперва он из всех данных строит все в принципе возможные комбинации, а затем отбрасывает те, которые не соответствуют критериям. Всем. Сразу. Итак. Первый критерий - максимальная длина префикса в разрезе оператора, применимая к данному номеру. Отбор по нему тебе придётся делать в подзапросе - потому что формирование этого критерия требует группировки. Второй критерий - это соответствие первому критерию и первая позиция при сортировке по возрастанию цены. Отбор по нему будет в основном запросе. Подзапрос, конечно, не здОрово. Но т.к. моб.операторов сравнительно мало, то результат подзапроса будет достаточно компактным, а сам подзапрос быстрым, несмотря на то, что используется функция и, соответственно, фуллскан. Впрочем, если он будет узким местом, есть способы значительно ускорить его за счёт небольшой корректировки структуры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2016, 21:44 |
|
||
|
Выборка лучшего значения по двум параметрам
|
|||
|---|---|---|---|
|
#18+
Akina, Akina, ну с субзапросом мало-мальски понятно- MariaDB [price_comparison]> select trunk,max(prefix) as prefix from price where (79283170000 like concat (prefix,'%')) group by trunk; +------------+-------------+ | trunk | prefix | +------------+-------------+ | bestvoip | 79 | | ringtime | 792 | | siptraffic | 7928 | +------------+-------------+ Тут у каждого оператора выбирается самый длинный префикс. Но вот как его скормить основному запросу, чтобы передать ему пару trunk-prefix (id или иного уникального поля у таблицы нет) - пока не соображу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.10.2016, 22:08 |
|
||
|
|

start [/forum/topic.php?fid=47&fpage=89&tid=1831285]: |
0ms |
get settings: |
5ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
44ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
24ms |
get tp. blocked users: |
1ms |
| others: | 248ms |
| total: | 345ms |

| 0 / 0 |
