Php 需要根据与同一列/表中其他日期相关的日期筛选MySQL结果
我有一个MySQL表,其结构如下:Php 需要根据与同一列/表中其他日期相关的日期筛选MySQL结果,php,mysql,Php,Mysql,我有一个MySQL表,其结构如下: ID (int) (PK) PersonID (int) EventDate (date) 我需要做的是在另一个EventDate的14天内检索所有PersonID,其中有一个EventDate Sample Data: ID PersonID EventDate 1 101 2011-01-01 2 102 2011-02-01 3 103 2011-03-01 4
ID (int) (PK)
PersonID (int)
EventDate (date)
我需要做的是在另一个EventDate的14天内检索所有PersonID,其中有一个EventDate
Sample Data:
ID PersonID EventDate
1 101 2011-01-01
2 102 2011-02-01
3 103 2011-03-01
4 104 2011-04-01
5 105 2011-04-11
6 106 2011-04-21
7 107 2011-05-01
8 108 2011-06-01
9 109 2011-07-01
10 110 2011-08-01
Desired Results:
104
105
106
107
我还没有找到解决这个问题的办法
我可以用PHP实现,但我更喜欢用MySQL直接实现
谢谢你的帮助。我相信它应该对你有用
// #1 - quite slow
SELECT a.PersonID,
(SELECT COUNT(*)
FROM table1 b WHERE b.ID != a.ID
AND a.EventDate BETWEEN
(b.EventDate - INTERVAL 14 DAY AND b.EventDate + INTERVAL 14 DAY)
) as cnt
FROM table1 a
HAVING cnt >0
// or #2 - should be much faster
SELECT DISTINCT a.PersonID
FROM table1 a
INNER JOIN table1 b ON (b.ID != a.ID AND a.EventDate BETWEEN
(b.EventDate - INTERVAL 14 DAY AND b.EventDate + INTERVAL 14 DAY))
我相信它应该对你有用
// #1 - quite slow
SELECT a.PersonID,
(SELECT COUNT(*)
FROM table1 b WHERE b.ID != a.ID
AND a.EventDate BETWEEN
(b.EventDate - INTERVAL 14 DAY AND b.EventDate + INTERVAL 14 DAY)
) as cnt
FROM table1 a
HAVING cnt >0
// or #2 - should be much faster
SELECT DISTINCT a.PersonID
FROM table1 a
INNER JOIN table1 b ON (b.ID != a.ID AND a.EventDate BETWEEN
(b.EventDate - INTERVAL 14 DAY AND b.EventDate + INTERVAL 14 DAY))
这很接近:
SELECT DISTINCT parent.PersonID, child.PersonID, DATEDIFF(parent.EventDate, child.EventDate) AS diff
FROM testdata AS parent
JOIN testdata AS child ON ABS(DATEDIFF(parent.EventDate, child.EventDate)) < 14
WHERE (parent.personID <> child.personID)
选择不同的parent.PersonID、child.PersonID、DATEDIFF(parent.EventDate、child.EventDate)作为差异
从testdata作为父级
将testdata作为ABS上的子项加入(DATEDIFF(parent.EventDate,child.EventDate))<14
其中(parent.personID child.personID)
使用
mysql>从testdata中选择*;
+------+----------+---------------------+
|ID | PersonID |事件日期|
+------+----------+---------------------+
| 1 | 101 | 2011-01-01 00:00:00 |
| 2 | 102 | 2011-02-01 00:00:00 |
| 3 | 103 | 2011-03-01 00:00:00 |
| 4 | 104 | 2011-04-01 00:00:00 |
| 5 | 105 | 2011-04-11 00:00:00 |
| 6 | 106 | 2011-04-21 00:00:00 |
| 7 | 107 | 2011-05-01 00:00:00 |
| 8 | 108 | 2011-06-01 00:00:00 |
| 9 | 109 | 2011-07-01 00:00:00 |
| 10 | 110 | 2011-08-01 00:00:00 |
+------+----------+---------------------+
一组10行(0.00秒)
mysql>选择DISTINCT parent.PersonID,child.PersonID,DATEDIFF(parent.EventDate,child.EventDate)作为diff从testdata作为parent连接testdata作为ABS上的child(DATEDIFF(parent.EventDate,child.EventDate))<14其中(parent.PersonID child.PersonID);
+----------+----------+------+
|PersonID | PersonID | diff|
+----------+----------+------+
| 105 | 104 | 10 |
| 104 | 105 | -10 |
| 106 | 105 | 10 |
| 105 | 106 | -10 |
| 107 | 106 | 10 |
| 106 | 107 | -10 |
+----------+----------+------+
一组6行(0.00秒)
mysql>
现在的缺点是,它认为105/104与104/105不同(它们是不同的,但只是彼此的镜像)。这很接近:
SELECT DISTINCT parent.PersonID, child.PersonID, DATEDIFF(parent.EventDate, child.EventDate) AS diff
FROM testdata AS parent
JOIN testdata AS child ON ABS(DATEDIFF(parent.EventDate, child.EventDate)) < 14
WHERE (parent.personID <> child.personID)
选择不同的parent.PersonID、child.PersonID、DATEDIFF(parent.EventDate、child.EventDate)作为差异
从testdata作为父级
将testdata作为ABS上的子项加入(DATEDIFF(parent.EventDate,child.EventDate))<14
其中(parent.personID child.personID)
使用
mysql>从testdata中选择*;
+------+----------+---------------------+
|ID | PersonID |事件日期|
+------+----------+---------------------+
| 1 | 101 | 2011-01-01 00:00:00 |
| 2 | 102 | 2011-02-01 00:00:00 |
| 3 | 103 | 2011-03-01 00:00:00 |
| 4 | 104 | 2011-04-01 00:00:00 |
| 5 | 105 | 2011-04-11 00:00:00 |
| 6 | 106 | 2011-04-21 00:00:00 |
| 7 | 107 | 2011-05-01 00:00:00 |
| 8 | 108 | 2011-06-01 00:00:00 |
| 9 | 109 | 2011-07-01 00:00:00 |
| 10 | 110 | 2011-08-01 00:00:00 |
+------+----------+---------------------+
一组10行(0.00秒)
mysql>选择DISTINCT parent.PersonID,child.PersonID,DATEDIFF(parent.EventDate,child.EventDate)作为diff从testdata作为parent连接testdata作为ABS上的child(DATEDIFF(parent.EventDate,child.EventDate))<14其中(parent.PersonID child.PersonID);
+----------+----------+------+
|PersonID | PersonID | diff|
+----------+----------+------+
| 105 | 104 | 10 |
| 104 | 105 | -10 |
| 106 | 105 | 10 |
| 105 | 106 | -10 |
| 107 | 106 | 10 |
| 106 | 107 | -10 |
+----------+----------+------+
一组6行(0.00秒)
mysql>
现在的缺点是,它认为105/104与104/105不同(它们是,但只是彼此的镜像)。在PHP中,可以这样做:
$data = array(...); // fetched data
$result = array();
$tmp = array();
foreach ( $data as $row ) {
$timestamp = strtotime($row['EventDate']);
$tmp[ $timestamp ] = $row;
}
ksort($tmp);
$prevRow = array();
$prevTimestamp = 0;
$diff = 60 * 60 * 24 * 14; // 14 days
$prevMatched = true;
foreach ( $tmp as $timestamp => $row ) {
if ( empty($prevTimestamp) ) {
$prevRow = $row;
$prevTimestamp = $timestamp;
continue;
}
if ( ( $timestamp - $prevTimestamp ) <= $diff ) {
$result[] = $row;
$prevMatched = true;
} else {
if ( $prevMatched ) {
$result[] = $prevRow;
}
$prevMatched = false;
}
}
var_dump($result);
$data=array(…);//获取的数据
$result=array();
$tmp=array();
foreach($行数据){
$timestamp=strottime($row['EventDate']);
$tmp[$timestamp]=$row;
}
k港口(tmp);
$prevRow=array();
$prevTimestamp=0;
$diff=60*60*24*14;//14天
$prevMatched=true;
foreach($tmp作为$timestamp=>$row){
if(空($prevTimestamp)){
$prevRow=$row;
$prevTimestamp=$timestamp;
继续;
}
如果在PHP中(($timestamp-$prevTimestamp),您可以这样做:
$data = array(...); // fetched data
$result = array();
$tmp = array();
foreach ( $data as $row ) {
$timestamp = strtotime($row['EventDate']);
$tmp[ $timestamp ] = $row;
}
ksort($tmp);
$prevRow = array();
$prevTimestamp = 0;
$diff = 60 * 60 * 24 * 14; // 14 days
$prevMatched = true;
foreach ( $tmp as $timestamp => $row ) {
if ( empty($prevTimestamp) ) {
$prevRow = $row;
$prevTimestamp = $timestamp;
continue;
}
if ( ( $timestamp - $prevTimestamp ) <= $diff ) {
$result[] = $row;
$prevMatched = true;
} else {
if ( $prevMatched ) {
$result[] = $prevRow;
}
$prevMatched = false;
}
}
var_dump($result);
$data=array(…);//获取的数据
$result=array();
$tmp=array();
foreach($行数据){
$timestamp=strottime($row['EventDate']);
$tmp[$timestamp]=$row;
}
k港口(tmp);
$prevRow=array();
$prevTimestamp=0;
$diff=60*60*24*14;//14天
$prevMatched=true;
foreach($tmp作为$timestamp=>$row){
if(空($prevTimestamp)){
$prevRow=$row;
$prevTimestamp=$timestamp;
继续;
}
if($timestamp-$prevTimestamp)#2在删除BETWEEN参数周围的()后工作得很好。谢谢。我还觉得自己像个傻瓜,忘记了将表连接到它自己。Doh!#2在删除()围绕着中间的争论。谢谢你。我也觉得自己像个白痴,因为我忘了把桌子连在一起。啊!