在其他条件行之后查找某些条件的行

时间:2016-08-22 14:58:30

标签: mysql sql pdo count

为了衡量免费产品获得新客户的有效性,我想找到仅在收到免费订单后支付订单的客户数量。我的表看起来像:

id | user | total
-----------------
 1    1     0.00
 2    1     57.33
 3    2     58.21
 4    2     0.00
 5    3     26.10
 6    3     0.00
 7    3     64.94
 8    4     0.00
 9    5     34.54

在此表中有五位客户:12345。这是我能想到的所有条件的重要因素。

  • 用户1收到了免费订单,然后下了付款订单,这就算了
  • 用户2下了付款订单,然后收到了免费订单,这不算
  • 用户3下了付款订单,然后收到了免费订单,然后下了付款订单,这不计算
  • 用户4收到了免费订单,这不算
  • 用户5下了付款订单,这不算

您可以看到我只关心在收到免费订单之前没有下订单的用户,然后下了付费订单。我正在寻找的计数的更具说明性的定义是:

  • 用户在收到n订单n->total > 0m后,在m->total == 0处下了订单m->id < n->idww->total > 0
  • 没有订单w->id < m->id

一些create table代码:

create table orders (
    id int NOT NULL AUTO_INCREMENT,
    user int,
    total decimal(6,2),
    PRIMARY KEY(id)
);

insert into orders (user, total) values
    (1, 0.00),
    (1, 57.33),
    (2, 58.21),
    (2, 0.00),
    (3, 26.10),
    (3, 0.00),
    (3, 64.94),
    (4, 0.00),
    (5, 34.54);

这种情况下的预期输出为1

4 个答案:

答案 0 :(得分:2)

简单聚合与条件聚合相结合,可以为您提供所需的用户。

SELECT
    [user]
    ,MIN(id) as MinId
    ,MIN(CASE WHEN total = 0 THEN id END) as MinZeroId
    ,MIN(CASE WHEN total > 0 THEN id END) as MinPositiveId
FROM
    orders
GROUP BY
    [user]
HAVING
    MIN(id) = MIN(CASE WHEN total = 0 THEN id END)
    AND MIN(CASE WHEN total > 0 THEN id END) > MIN(CASE WHEN total = 0 THEN id END)

将用户的最小ID与总计$ 0的最小ID进行比较,然后比较总计&gt;的最小ID。 $ 0到最低ID为$ 0 Total。

如果您想要原始记录,只需添加一个外部选择即可到达。

SELECT o.*
FROM
    (
       SELECT
          [user]
       FROM
          orders
       GROUP BY
          [user]
       HAVING
          MIN(id) = MIN(CASE WHEN total = 0 THEN id END)
          AND MIN(CASE WHEN total > 0 THEN id END) > MIN(CASE WHEN total = 0 THEN id END)
    ) t
    INNER JOIN orders o
    ON t.[user] = o.[user]

答案 1 :(得分:0)

您想要第一条记录(where子句)总计为零的记录对(自连接),并且存在总计非零的后续记录。 (不一定是下一个记录,对吗?)

Select i.User, i.total firstTotal, 
    n.Total firstpaidTotal 
from table i
  join table n
     on n.Id > i.id
         and n.user = i.user
         and n.total > 0
where i.total = 0
  and not exists 
   (Select * from table
    where user = i.user
       and id < i.Id)           

答案 2 :(得分:0)

这可能会解决您的问题:

select a.id from orders a
join orders b on (a.user = b.user and a.id < b.id and a.total = 0)
join (select min(id) as id, user from orders group by user) c on (a.user = c.user and a.id = c.id)

如果出现任何问题,请告诉我。)

答案 3 :(得分:0)

另一个可能的解决方案,虽然我个人喜欢@Matt回答这个问题:

SELECT a.user
FROM orders a
  -- search first user_line
  JOIN (
      SELECT b.user, MIN(b.id) first_id
      FROM orders b
      GROUP BY b.user
    ) c ON a.user = c.user AND a.id = c.first_id
WHERE
  -- check first line is total=0
  a.total = 0
  -- has later lines with total>0
  AND EXISTS (
      SELECT 'exists'
      FROM orders c
      WHERE 
        c.user = a.user 
        AND c.total > 0
        AND c.id > a.id
    )