2013-05-31 163 views
0

我正在尝试创建一个执行以下操作的SQL语句,但显然会失败。复杂SQL选择语句

选择来自它基于下面的准则的视图和过滤器的所有信息:

  1. 如果给定的字段“CUSTOMER_NUMBER”存在于表格中的任何点
  2. 然后检查内的任何重复最近30天
  3. 然后输出按客户编号分组的所有不同customer_numbers
  4. 有一个计数,以便我可以看到一个项目重复了多少次。

所以今天使用作为我们当前的日期说,我在我的表中的下列数据项:

customer_number, date 
111111, 2013-01-01 
111111, 2013-05-05 
222222, 2013-01-07 
222222, 2013-03-19 
333333, 2013-05-15 
333333, 2013-05-30 

我希望我的SELECT语句返回如下:

customer_number, date, count 
111111, 2013-01-01, 2 
333333, 2013-05-15, 2 

而且客户222222将不会显示,因为他在过去30天内没有出现。

这里是关于我试图弄清楚这一点。它仅返回当前月份的数据。

SELECT *, COUNT(customer_number) 
FROM red_flags 
WHERE dealer_id = '75' AND date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() 
GROUP BY customer_number 
HAVING COUNT(customer_number) > 1 

我已经融化我的大脑试图找出如何或者如果这甚至有可能做一个查询任何帮助将不胜感激!

+0

如何选择日期 - 是否总是选择MIN()? – sgeddes

+0

@sgeddes日期应该是它第一次出现在表格中。 – bmanhard

回答

1

这里是如何做到这一点使用JOIN

select r.customer_number, count(*) ct, min(date) minDate 
from red_flags r 
join (select distinct customer_number 
     from red_flags 
     where dealer_id = '75' 
     and date between CURDATE() - INTERVAL 30 DAY and CURDATE()) x 
ON r.customer_number = x.customer_number 
group by customer_number 
HAVING ct > 1 

SQLFIDDLE

+0

这工作完美,超快感谢吨! – bmanhard

+0

为什么MySQL在优化IN时如此糟糕?在阅读更多内容之前,我没有意识到这一点。感谢您的关注。顺便说一句 - 我认为我编辑的内容可能是最好的解决方案。亲切的问候! – sgeddes

+0

@sgeddes看看EXPLAIN - 它倾向于使用错误的索引。它不是选择子查询中的项目,然后将它们编入主表中,而是扫描整个主表,然后索引到子查询中。 – Barmar

1

像这样的东西应该适合你 - 它使用子查询来找出哪些客户在过去30天内被标记过。然后它使用COUNT获得总数,并使用MIN获得第一个日期。

SELECT customer_number, COUNT(1), MIN(date) minDate 
FROM red_flags 
WHERE customer_number IN (
    SELECT customer_number 
    FROM red_flags 
    WHERE dealer_id = '75' 
     AND date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() 
) 
GROUP BY customer_number 

如果你只关心那些有多个记录,你可以添加HAVING子句。

BTW,使用BETWEEN的日期要小心。我更喜欢明确地使用> =和< =来获得更多控制。


编辑 - 也许是最简单的解决方案,使用次数与CASE:

SELECT customer_number, COUNT(1), MIN(date) minDate 
FROM red_flags 
GROUP BY customer_number 
HAVING COUNT(CASE WHEN date BETWEEN CURDATE() - INTERVAL 30 DAY AND CURDATE() THEN 1 END) > 0 
+0

似乎工作,它采取我的数据库~45秒来解析这个查询,有没有什么办法来加速它呢? – bmanhard

+0

@bmanhard - 哇,这是很长的时间。你有在customer_id字段的索引吗? – sgeddes

+0

我也只关心有多个记录的项目,我在GROUP BY下面添加了HAVING COUNT(customer_number)> 1,它不再返回记录。 – bmanhard