2017-01-31 7 views
0

У меня есть эта таблица:Выберите сочетание строк на основе конкретных значений

WeekID ISModelled ProductID Units Value 
1  MODEL  123   0  0 
2  EPOS  123   0  0 
2  MODEL  123   100  50 
3  IMPUTE  987   100  50 
4  MODEL  123   100  50 
4  EPOS  987   100  50 
4  EPOS  123   100  50 
5  EPOS  987   0  0 
5  MODEL  987   100  50 

И я хочу, чтобы получить эту возможную комбинацию из нее:

WeekID ISModelled ProductID Units Value 
2  EPOS  123   0  0 
2  MODEL  123   100  50 
5  EPOS  987   0  0 
5  MODEL  987   100  50 

Я хочу, чтобы выбрать на ProductID, по WeekID, любая комбинация, где столбец ISModelled с «EPOS» имеет значение 0 в столбцах Units и Value и где столбец IsModelled с моделью имеет любое значение выше 0 в Units и Value столбцов.

Цените всю помощь!

+0

Почему только 2 для модели в результирующем наборе? –

+0

Потому что в WeekID = 1 есть только 1 результат модели без EPOS (так что я этого не хочу), а в WeekID = 4 ProductID 123 с EPOS имеет значение выше 0, и я не хочу их –

+0

@MartaLopes, я обновил мои решение. –

ответ

0

Это похоже на проблему с совпадающими парами с univot с возможностью совпадений или несколькими совпадениями - выделение номера строки должно помочь с этой возможностью .

/*> drop table if exists t; 
    /*> create table t (
    /*> WeekID int, ISModelled varchar(10), ProductID int, Units int, Value int); 
    /*> insert into t values 
    /*> (1 ,  'MODEL' , 123 ,  0 , 0), 
    /*> (2 ,  'EPOS' , 123 ,  0 , 0), 
    /*> (2 ,  'MODEL' , 123 ,  100 , 50), 
    /*> (3 ,  'IMPUTE' , 987 ,  100 , 50), 
    /*> (4 ,  'MODEL' , 123 ,  100 , 50), 
    /*> (4 ,  'EPOS' , 987 ,  100 , 50), 
    /*> (4 ,  'EPOS'  , 123 ,  100 , 50), 
    /*> (5 ,  'EPOS' , 987 ,  0 , 0), 
    /*> (5 ,  'MODEL' , 987 ,  100 , 50); 
    /*> */ 
MariaDB [sandbox]> select S.* from 
    -> (
    -> select t.ISModelled Smodelled, 
    -> t.* , 
    -> if(t.WeekID <> @pw ,@rne:=1,@rne:[email protected]+1) rne, 
    -> @pw:=t.weekid 
    -> from (select @rne:=0,@pw:=0) rn,t 
    -> where t.ismodelled = 'EPOS' and t.units = 0 and t.Value = 0 
    -> order by t.weekid 
    ->) s 
    -> join 
    -> (
    -> select t.ISModelled Mmodelled, 
    -> t.* , 
    -> if(t.WeekID <> @pw ,@rne:=1,@rne:[email protected]+1) rne, 
    -> @pw:=t.weekid 
    -> from (select @rne:=0,@pw:=0) rn,t 
    -> where t.ismodelled = 'MODEL' and t.units > 0 and t.Value > 0 
    -> order by t.weekid 
    ->) t on t.weekid = s.weekid and t.rne = s.rne and t.productid = s.productid 
    -> where Smodelled = 'EPOS' 
    -> union ALL 
    -> select T.* from 
    -> (
    -> select t.ISModelled Emodelled, 
    -> t.* , 
    -> if(t.WeekID <> @pw ,@rne:=1,@rne:[email protected]+1) rne, 
    -> @pw:=t.weekid 
    -> from (select @rne:=0,@pw:=0) rn,t 
    -> where t.ismodelled = 'EPOS' and t.units = 0 and t.Value = 0 
    -> order by t.weekid 
    ->) s 
    -> join 
    -> (
    -> select t.ISModelled Mmodelled, 
    -> t.* , 
    -> if(t.WeekID <> @pw ,@rne:=1,@rne:[email protected]+1) rne, 
    -> @pw:=t.weekid 
    -> from (select @rne:=0,@pw:=0) rn,t 
    -> where t.ismodelled = 'MODEL' and t.units > 0 and t.Value > 0 
    -> order by t.weekid 
    ->) t on t.weekid = s.weekid and t.rne = s.rne and t.productid = s.productid 
    -> where Mmodelled = 'MODEL' 
    -> ORDER BY WEEKID,ISMODELLED,RNE 
    -> 
    -> 
    -> 
    -> ; 
+-----------+--------+------------+-----------+-------+-------+------+---------------+ 
| Smodelled | WeekID | ISModelled | ProductID | Units | Value | rne | @pw:=t.weekid | 
+-----------+--------+------------+-----------+-------+-------+------+---------------+ 
| EPOS  |  2 | EPOS  |  123 |  0 |  0 | 1 |    2 | 
| MODEL  |  2 | MODEL  |  123 | 100 | 50 | 1 |    2 | 
| EPOS  |  5 | EPOS  |  987 |  0 |  0 | 1 |    5 | 
| MODEL  |  5 | MODEL  |  987 | 100 | 50 | 1 |    5 | 
+-----------+--------+------------+-----------+-------+-------+------+---------------+ 
4 rows in set (0.00 sec) 
+0

Зачем спрашивать? –

+0

Многословие вашего ответа. Если вы отредактируете сообщение, я удалю downvote (нет возможности сделать это без вашего редактирования). Ваш запрос выполняет эту работу, но это сложно. –

+0

@Grzegorz Górkiewicz У меня, возможно, был сложный вопрос - с другой стороны, вы, возможно, упростили. Рассмотрим случай, когда в weekid 5 есть 2 МОДЕЛИ, которые соответствуют критериям выбора, конечным результатом с использованием моего решения будет EPOS, MODEL, сопоставляемая с продуктом, используя ваше решение, это будет EPOS, MODEL, MODEL (и было бы безразлично, какой продукт он находит для МОДЕЛИ) - я не знаю, каков правильный результат из вопроса. –

0

Другие ответы здесь дают некоторые допустимые варианты, но для этого работает другой шаблон ANSI-SQL.

SELECT 
    * 
FROM 
    yourTable 
INNER JOIN 
(
    SELECT 
     WeekID, 
     ProductID 
    FROM 
     yourTable 
    WHERE 
      (IsModelled = 'MODEL' AND Units > 0 AND Value > 0) 
     OR (IsModelled = 'EPOS' AND Units = 0 AND Value = 0) 
    GROUP BY 
     WeekID, 
     ProductID 
    HAVING 
     COUNT(DISTINCT IsModelled) = 2 
) 
    matchingPairs 
     ON matchingPairs.WeekID = yourTable.WeekID 
     AND matchingPairs.ProductID = yourTable.ProductID 
WHERE 
    yourTable.IsModelled IN ('MODEL', 'EPOS') 
ORDER BY 
    WeekID, 
    ProductID, 
    IsModelled 

Это фактически функционально аналогичен ответу, который использует EXISTS с коррелировала-подзапроса. Однако производительность должна быть лучше из-за использования только одного подзапроса, и этот подзапрос не коррелируется (у которого MySQL часто имеет низкую производительность).

Он также выгоды от того, меньше повторяющегося кода и (на мой взгляд) ясное намерение (читаемость).

Примечание: Я предположил, что (WeekId, ProductID, IsModelled) уникален.

+0

весь заказ по товарам неоднозначен, и решение не создает четкую совпадающую пару - например, вы добавляете еще один weekid 5 MODEL 987, результат - EPOS, MODEL, MODEL –

+0

@ P.Salmon. В ORDER BY нет предложений там, которые влияют на логику. Что неоднозначно?Кроме того, я специально отмечаю предположение о уникальности (если он уникален, ваш пример становится нарушением ограничения). – MatBailie

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