确定在mysql

时间:2016-04-04 15:20:24

标签: mysql sql

我想确定使用mysql发生45天的客户访问。必须选择客户的第一次访问,必须选择在先前选择的访问后45天发生的以下访问。例如,我有以下样本访问表 -

Visit_ID    Cust_ID Vst_Beg_Dt  Vst_End_Dt  Post_45_Day_Dt  Selection Criteria
121         678     2015-07-02  2015-07-08  8/22/2015       select since it is the first visit
223         678     2015-10-25  2015-10-27  12/11/2015      select since the visit occurs after 45 days -  8/22/2015
229         678     2016-02-21  2016-02-23  4/8/2016        select since the visit occurs after 45 days of the previously selected visit - 12/11/2015
445         545     2015-11-23  2015-11-28  1/12/2016       select since it is the first visit
198         545     2016-01-07  2016-01-12  2/26/2016       not selected since the visit is not after 45 days
271         545     2016-01-19  2016-01-29  3/14/2016       select since the visit occurs after 45 days of the previously selected visit - 12/11/2015
841         291     2015-09-08  2015-09-12  10/27/2015      select since it is the first visit
987         291     2015-12-19  2015-12-23  2/6/2016        select since the visit occurs after 45 days - 10/27/2015
211         291     2015-12-26  2016-01-06  2/20/2016       not selected since the visit is not after 45 days
122         291     2016-02-25  2016-02-27  4/12/2016       select since the visit occurs after 45 days of the previously selected visit - 2/6/2016

预期输出必须只有以下记录 -

Visit_ID    Cust_ID Vst_Beg_Dt  Vst_End_Dt      
121         678     2015-07-02  2015-07-08      
223         678     2015-10-25  2015-10-27      
229         678     2016-02-21  2016-02-23      
445         545     2015-11-23  2015-11-28      
271         545     2016-01-19  2016-01-29      
841         291     2015-09-08  2015-09-12      
987         291     2015-12-19  2015-12-23      
122         291     2016-02-25  2016-02-27

这可能吗?当客户有超过2次访问时,我遇到问题以确定上次访问。谢谢!

1 个答案:

答案 0 :(得分:0)

test this query:

SELECT * FROM (
  SELECT cv.*
  , CASE WHEN DATE_ADD(@d, INTERVAL 45 DAY) >= Vst_Beg_Dt AND Cust_ID = @c THEN @d
    WHEN DATE_ADD(@d, INTERVAL 45 DAY) < Vst_Beg_Dt AND Cust_ID = @c THEN @d := Vst_End_Dt
    WHEN (@c := Cust_ID) AND (@d := Vst_End_Dt) THEN @d END AS end45
  FROM customer_visits AS cv, (SELECT @d := CURDATE(), @c := 0) AS p 
  ORDER BY Cust_ID, Vst_Beg_Dt ) part_by_End_Dt45
WHERE Vst_End_Dt = end45
ORDER BY Cust_ID DESC, Vst_Beg_Dt ASC;

Subquery do partitioning, store first Vst_End_Dt date for current cust_id in variable @d, if Vst_Beg_Dt > @d + 45 or cust_id changed then again set @d = Vst_End_Dt. Value of @d is returned in end45.
Final query filter end45 = Vst_End_Dt, so if Vst_End_Dt <> @d row is spiked.

EDIT:
I don't know what you expect more, this query return result exactly like posted by you.

SQL Fiddle

MySQL 5.6 Schema Setup:

CREATE TABLE customer_visits
    ( Visit_ID        INT
  , Cust_ID         INT
  , Vst_Beg_Dt      DATE
  , Vst_End_Dt      DATE
  , Post_45_Day_Dt  DATE
  , Selection_Criteria VARCHAR(90))
;

INSERT INTO customer_visits
    (Visit_ID, Cust_ID, Vst_Beg_Dt, Vst_End_Dt, Post_45_Day_Dt, Selection_Criteria)
VALUES
  (121, 678, '2015-07-02', '2015-07-08', '2015-08-22', 'select since it is the first visit'),
  (223, 678, '2015-10-25', '2015-10-27', '2015-12-11', 'select since the visit occurs after 45 days - 8/22/2015'),
  (229, 678, '2016-02-21', '2016-02-23', '2016-04-08', 'select since the visit occurs after 45 days of the previously selected visit - 12/11/2015'),
  (445, 545, '2015-11-23', '2015-11-28', '2016-01-12', 'select since it is the first visit'),
  (198, 545, '2016-01-07', '2016-01-12', '2016-02-26', 'not selected since the visit is not after 45 days'),
  (271, 545, '2016-01-19', '2016-01-29', '2016-03-14', 'select since the visit occurs after 45 days of the previously selected visit - 12/11/2015'),
  (841, 291, '2015-09-08', '2015-09-12', '2015-10-27', 'select since it is the first visit'),
  (987, 291, '2015-12-19', '2015-12-23', '2016-02-06', 'select since the visit occurs after 45 days - 10/27/2015'),
  (211, 291, '2015-12-26', '2016-01-06', '2016-02-20', 'not selected since the visit is not after 45 days'),
  (122, 291, '2016-02-25', '2016-02-27', '2016-04-12', 'select since the visit occurs after 45 days of the previously selected visit - 2/6/2016')

;

Query 1:

SELECT Visit_ID
, Cust_ID
, DATE_FORMAT(Vst_Beg_Dt, '%Y-%m-%d') as Beg_Dt
, DATE_FORMAT(Vst_End_Dt, '%Y-%m-%d') as End_Dt
, Selection_Criteria
FROM (
  SELECT cv.*
  , CASE WHEN DATE_ADD(@d, INTERVAL 45 DAY) >= Vst_Beg_Dt AND Cust_ID = @c THEN @d
    WHEN DATE_ADD(@d, INTERVAL 45 DAY) < Vst_Beg_Dt AND Cust_ID = @c THEN @d := Vst_End_Dt
    WHEN (@c := Cust_ID) AND (@d := Vst_End_Dt) THEN @d END AS end45
  FROM customer_visits AS cv, (SELECT @d := CURDATE(), @c := 0) AS p 
  ORDER BY Cust_ID, Vst_Beg_Dt ) part_by_End_Dt45
WHERE Vst_End_Dt = end45
ORDER BY Cust_ID DESC, Vst_Beg_Dt ASC

Results:

| Visit_ID | Cust_ID |     Beg_Dt |     End_Dt |                                                                        Selection_Criteria |
|----------|---------|------------|------------|-------------------------------------------------------------------------------------------|
|      121 |     678 | 2015-07-02 | 2015-07-08 |                                                        select since it is the first visit |
|      223 |     678 | 2015-10-25 | 2015-10-27 |                                   select since the visit occurs after 45 days - 8/22/2015 |
|      229 |     678 | 2016-02-21 | 2016-02-23 | select since the visit occurs after 45 days of the previously selected visit - 12/11/2015 |
|      445 |     545 | 2015-11-23 | 2015-11-28 |                                                        select since it is the first visit |
|      271 |     545 | 2016-01-19 | 2016-01-29 | select since the visit occurs after 45 days of the previously selected visit - 12/11/2015 |
|      841 |     291 | 2015-09-08 | 2015-09-12 |                                                        select since it is the first visit |
|      987 |     291 | 2015-12-19 | 2015-12-23 |                                  select since the visit occurs after 45 days - 10/27/2015 |
|      122 |     291 | 2016-02-25 | 2016-02-27 |   select since the visit occurs after 45 days of the previously selected visit - 2/6/2016 |