I have a database that has 2 columns Left_From and Left_To I need to basically check both columns with each row in the database to see if there is any overlapping ranges. So lets say there are 37 rows returned I need to check each row 37 times. I have tried array_intersect() with ranges and multiple loops. I have also tried BETWEEN in mysql but that does do what I need it to either. When I tried the between method I have two loops that I thought would take these two
$newstart[$crow] = $row['LEFT_FROM'];
$newend[$crow] = $row['LEFT_TO'];
and compare them to the new data that would be looped through 37 times because of $row2.
//attempt at BETWEEN
$newstart = array();
$newend = array();
$crow = 0;
while ($row = mysqli_fetch_array($get)) {
$newstart[$crow] = $row['LEFT_FROM'];
$newend[$crow] = $row['LEFT_TO'];
while ($row2 = mysqli_fetch_array($get)) {
$newsql = "SELECT * FROM database+table WHERE tablename = 'something' AND
LEFT_FROM BETWEEN " . $newstart[$crow] . " AND " . $newend[$crow] . " OR
LEFT_TO BETWEEN " . $newstart[$crow] . " AND " . $newend[$crow] . " OR ".
$newstart[$crow] . " BETWEEN " . "LEFT_FROM" . " AND ". " LEFT_TO";
$result = mysqli_query($GLOBALS['Con'], $newsql);
if (!$result) {
echo "Error: " . mysqli_error($GLOBALS['Con']) . "<br>";
}
if (!empty($result)) {
echo "Overlap: ". "Row2 LEFT_FROM: " . $row2['LEFT_FROM'] . " NewStart: " . $newstart[$crow] . " Row2 LEFT_TO: " . $row2['LEFT_TO'] . " Newend: " . $newend[$crow] . "<br>" . "Crow: " . $crow . "<br>" ;
}
}
echo "Crow: " . $crow . "<br>";
$crow++;
}
atempt at array_intersect all variables in arrays are set to 0
$result = mysqli_query($GLOBALS['con'], $select);
$Rows = $result->num_rows;
$Rows2 = $Rows;
$Rows3 = $Rows;
$Rows4 = $Rows;
$Rows5 = $Rows;
$range1 = array();
$range2 = array();
$range3 = array();
$range4 = array();
while ($counter <= $Rows) {
$range1[$crow] = $leftfrom[$add];
$range2[$crow] = $leftto[$add];
$counter++;
$road++;
$crow++;
}
while ($counter2 <= $Rows2) {
$range3[$crow2] = $leftfrom[$add2];
$range4[$crow2] = $leftto[$add2];
$counter2++;
$road3++;
$crow2++;
}
$Combined1 = array();
$Combined1 = array();
while ($counter3 <= $Rows3) {
$Combined1[$crow5] = range($range1[$crow3], $range2[$crow3]);
$Combined2[$crow6] = range($range3[$crow3], $range4[$crow3]);
$crow5++;
$crow6++;
$crow3++;
$counter3++;
}
$check1 = 0;
while ($check1 <= $Rows4) {
$GLOBALS['check2'] = 0;
$Rows6 = $GLOBALS['check2'] + 1;
while ($GLOBALS['check2'] <= $Rows5) {
$results = array_intersect($Combined1[$check1],$Combined2[$Rows6]);
if ($results) {
$start = reset($results);
$end = end($results);
echo "These are overlapping" . "<br>";
echo "Start of overlap: " . $start . " Rows#: " . $check1 . " Bad Row: " . $GLOBALS['check2'];
echo "<br>";
echo "end of overlap: " . $end;
echo "<br>" . $GLOBALS['check2'] ;
$GLOBALS['check2']++;
}else{
echo "<br>" . $check1 . " No duplicates" . "<br>";
$GLOBALS['check2']++;
}
}
$check1++;
}
You don't need a loop in PHP, you can do it entirely by joining the table with itself.
SELECT *
FROM yourTable AS t1
JOIN yourTable AS t2
ON t1.id < t2.id
AND (t1.left_from <= t2.left_to AND t2.left_from <= t1.left_to)
t1.id < t2.id
keeps it from treating a row as overlapping with itself (and using <
rather than !=
keeps it from showing the same pair of rows twice). Replace id
with the primary key of your table.
To check, if two number ranges overlap, you could use the simple test x1 < y2 AND y1 < x2
. This could be combined in a single sql statement.
SELECT
t1.LEFT_FROM as LEFT_FROM_1,
t1.LEFT_TO as LEFT_TO_1,
t2.LEFT_FROM as LEFT_FROM_2,
t2.LEFT_TO as LEFT_TO_2
FROM
t t1, t t2
WHERE
t1.LEFT_FROM < t2.LEFT_TO AND t2.LEFT_FROM < t1.LEFT_TO
This query would return all overlapping ranges.