Mysql 根据特定值选择行的组合

Mysql 根据特定值选择行的组合,mysql,sql,combinations,Mysql,Sql,Combinations,我有这张桌子: 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

我有这张桌子:

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
我想通过WeekID在ProductID上选择任意组合,其中带EPOS的IsModeled列在Units和value列中的值为0,而带Model的IsModeled列在Units和value列中的值大于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:=@rne+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:=@rne+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:=@rne+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:=@rne+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)

这里的其他答案提供了一些有效的选项,但是还有另一个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、IsModeled是唯一的。

为什么结果集中的模型只有2个?因为在WeekId=1中只有1个没有EPO的模型结果,所以我不想要这些,在WeekId=4中,带有EPO的ProductID 123的值大于0,我不想要这些either@MartaLopes,我已经更新了我的解决方案。你的回答太详细了。如果你编辑了这篇文章,我将删除否决票,没有你的编辑我不可能这么做。你的问题可以解决,但它很复杂。@Grzegorz Górkiewicz我可能把问题复杂化了——另一方面,你可能过于简化了。考虑在星期5中有2个模型与选择标准相匹配的情况下,使用我的解决方案的最终结果将是EPOS,模型在使用您的解决方案的产品TimeD上匹配,它将是EPOS,模型,模型,它不关心它为模型找到哪个productid-我不知道问题的正确结果。让我们等待OP的反馈。如果你编辑你的帖子,我将删除否决票。没有你的编辑,技术上是不可能的。我同意@P.Salmon;我认为行应该由WeekID和ProductID进行匹配/配对。不幸的是,由于OP的评级如此之低,我发现它不太可能得到明确的澄清。所有按项目排序的顺序都不明确,解决方案也没有产生一个明显的匹配对-例如,您添加了另一个周末5 987型,结果是EPOS,MODEL,MODEL@P.Salmon其中没有影响逻辑的ORDER BY子句。什么是模棱两可的,另外,我特别注意到关于唯一性的假设,如果它是唯一的,那么您的示例将违反约束。