有条件地分组记录

时间:2014-03-21 18:18:56

标签: mysql sql

我的Google-fu在这个方面做得不够。我有一张交易表,如下:

id      email                   source      amount  timestamp
1       daniel@example.com      vendor      10      2014-03-10 23:34:40
2       john@example.com        website     15      2014-03-11 13:30:00
3       mary@example.com        website     50      2014-03-11 17:30:00
4       daniel@example.com      website     65      2014-03-13 20:06:30
5       mary@example.com        vendor      10      2014-03-14 16:20:30

我希望能够通过电子邮件对这些进行分组,但仅适用于以下用户: A)最初通过'供应商'来源进入,并且 B)还通过“网站”来源进行交易。
因此,对于上面的示例数据,我希望如此:

email                       total_amount        transactions
daniel@example.com          75                  2

玛丽不会被包括在内,因为她的第一笔交易是通过'网站',而不是'供应商'。约翰不会被包括在内,因为他根本没有通过供应商进行交易。

编辑:

不太理想,但仍然有用,就是这个结果集:

email                       total_amount        transactions
daniel@example.com          75                  2
mary@example.com            60                  2

Mary和Daniel都被包括在内,因为他们都至少在一次交易中通过'供应商'来源。

4 个答案:

答案 0 :(得分:2)

SELECT A.Email, sum(B.Amount) as Total_Amount, count(B.time) as Transactions
FROM tableName A
INNER join tableName B 
 on A.Email=B.Email 
 AND A.source='vendor' 
Group By A.Email

要求有点不清楚,因为您最初表明必须最初通过供应商,但随后您通过添加mary撤消该声明。

http://sqlfiddle.com/#!2/bb4f9/1/0

如果日期/时间戳很重要,请为A.Time< = B.Time添加AND子句并聚合A.Amoun t和A.time并添加类似...

SELECT A.Email, sum(B.Amount)+ sum(A.Amount) as Total_Amount, count(B.time)+count(A.Time) as Transactions
FROM tableName A
INNER join tableName B 
 on A.Email=B.Email 
 AND A.source='vendor'
 and A.Time<=B.Time
Group By A.Email

但这假设供应商条目只会针对每封电子邮件发生一次

因此,此解决方案首先找到供应商条目(如果电子邮件地址不止一个,这将无法返回准确的计数),那么它会找到同一电子邮件地址的任何条目,其后发生网站来源供应商条目并汇总该电子邮件的总数,并在供应商条目总计中添加。虽然它适用于所提供的相同数据,但如果同一电子邮件存在多个供应商条目,则可能无法按预期工作。如果不了解总数应该如何发生或者是否存在多个数据,或者根据这些数据理解为什么需要这些信息,我就无法在没有做出大量假设的情况下考虑更好的选择。

SELECT A.Email, sum(B.Amount)+sum(A.Amount) as Total_Amount, 
count(B.time)+count(A.Time) as Transactions
FROM tableName A
INNER join tableName B 
 on A.Email=B.Email 
 AND A.source='vendor'
 AND A.Time < B.Time and B.Source='website'
Group By A.Email

答案 1 :(得分:1)

在从这些人的记录中收集摘要信息之前,通过使用子查询查找具有初始“供应商”记录,然后是“网站”记录的人员,此查询应该为您提供所需的结果。

如果删除标有-- *的行,则还包括“供应商”记录不是第一个的人。

SELECT email, SUM(amount) AS total_amount, COUNT(*) AS transactions
FROM transactions
WHERE email IN 
    (SELECT t1.email FROM transactions t1
    LEFT JOIN transactions t0                                -- * 
    ON t0.email = t1.email AND t0.timestamp < t1.timestamp   -- *
    LEFT JOIN transactions t2 
    ON t2.email = t1.email 
    WHERE  t1.source = 'vendor' AND t2.source = 'website'
    AND t0.email IS NULL                                     -- *
    )
GROUP BY email;

请参阅http://www.sqlfiddle.com/#!2/864898/8/0

答案 2 :(得分:0)

您的查询应如下所示:

select email, sum(amount) ,count(*)
from tbl 
 where email='daniel@example.com'
group by email;

或 - 计算所有电子邮件!

select email, sum(amount) ,count(*)
from tbl 
group by email;

所有供应商

    select email, sum(amount) ,count(*)
    from tbl 
 where source ='vendor' 
    group by email;

此处还演示: http://sqlfiddle.com/#!2/de36ed/2

答案 3 :(得分:0)

试试这个: -

select x1.email_id,(x1.tot + x2.tot)as total_amount,(x1.cnt + x2.cnt)as transactions from 
(select t1.email_id,count(t1.email_id)as cnt,sum(t1.totalamt)as tot from testdata t1 where t1.sourcee='web' group by t1.email_id)x1
inner join (select t2.email_id,count(t2.email_id)as cnt,sum(t2.totalamt)as tot from testdata t2 where t2.sourcee='vendor' group by t2.email_id)x2
on x1.email_id=x2.email_id group by x1.email_id;

输出: -

enter image description here

它工作正常。如果需要,请根据您的表格结构更改字段名称。 希望它会对你有所帮助。