2017-01-31 17 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の場合、UnitsValue列に「EPOS」のあるISModelled列の値が0の任意の組み合わせで、のモデルのIsModelled列が0以上の値を持つ場合およびValueの列。

すべてのヘルプを評価してください!

+0

なぜMODELの結果セットは2だけですか? –

+0

WeekID = 1のため、EPOSのないモデル結果は1つしかないので(これは必要ありません)、WeekID = 4ではEPOSが0より大きい値を持っています。 –

+0

@MartaLopes、私は溶液。 –

答えて

0

これは、一致しない可能性のあるunpivotとのマッチングペアの問題、または複数のマッチのように見えます。行番号を割り当てると、 の可能性があります。

/*> 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

@GrzegorzGórkiewicz私は複雑な質問をしているかもしれません - 一方であなたは単純化されているかもしれません。週5の2つのモデルが選択基準に一致するケースを考えてください。ソリューションを使用した最終結果はEPOS、MODELはソリューションを使用するproductidと一致します。それは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を使用して答えるために機能的に類似しています。しかし、サブクエリを1つだけ使用するとパフォーマンスが向上するはずで、そのサブクエリは相関性がありません(MySQLのパフォーマンスが悪いことが多い)

また、(私の意見では)あまり繰り返しコードを有し、かつから明確な意思(読みやすさ)に利益をもたらします。

注:私は(WeekId, ProductID, IsModelled)が一意であることを前提としています。

+0

アイテムごとのすべての順序があいまいで、解決策は明確なマッチングペアを生成しません - たとえば、別のweekidを追加する5 MODEL 987結果はEPOS、MODEL、MODEL –

+0

@ P.Salmon ORDER BY節にはありませんそこには論理に影響を与えます。あいまいなのは何ですか?また、一意性についての前提にも注意します(一意であれば、例は制約違反になります)。 – MatBailie

関連する問題