我想确定使用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次访问时,我遇到问题以确定上次访问。谢谢!
答案 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.
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
| 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 |