Php 需要根据与同一列/表中其他日期相关的日期筛选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

我有一个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     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在删除()围绕着中间的争论。谢谢你。我也觉得自己像个白痴,因为我忘了把桌子连在一起。啊!