Last active
April 28, 2017 11:51
-
-
Save lennartvdd/b349c7a35c895e1568db052148d37de5 to your computer and use it in GitHub Desktop.
Simple Stand-alone SQL Query Builder written in PHP to help categorize objects by their dimensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* | |
Author: Lennart van den Dool | |
Date: 2017-03-10 | |
Purpose: Query Builder categorize objects by dimension (assuming cubiods) | |
If you run this script in the command line it will output some SQL that might help you get what you want. | |
This assumes the cuboid rotation is limited to the 6 permutations of l x b x h . | |
If the cubiod can be oriented otherwise (i.e. diagonally) the number of possible | |
rotations is infinate and there is no solution. | |
*/ | |
const COL_LENGTH = "length"; | |
const COL_WIDTH = "width"; | |
const COL_HEIGHT = "heigth"; | |
const TMP_TABLE = "tmp_dimension_categories"; | |
const SRC_TABLE = "product"; | |
$dimensionSet = [ | |
"15x20x30" => [15,20,30], | |
"50x30x30" => [50,30,30], | |
"100x50x50" => [100,50,50], | |
"other" => [9999999999,9999999999,9999999999], | |
]; | |
$weightSet = [ | |
"15x20x30" => 15, | |
]; | |
echo "-- this statement creates a temporary table used for grouping the result." . PHP_EOL; | |
echo "CREATE TABLE ".TMP_TABLE." ( | |
id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, | |
name VARCHAR(50) NOT NULL, | |
length INT(11) NOT NULL, | |
width INT(11) NOT NULL, | |
height INT(11) NOT NULL, | |
weight INT(11) NULL DEFAULT NULL | |
);"; | |
echo PHP_EOL; | |
echo "-- fill the temporary table with data" . PHP_EOL; | |
foreach ($dimensionSet as $name => $v) { | |
if (isset($weightSet[$name])) { | |
echo "INSERT INTO ".TMP_TABLE." (name, length, width, height, weight) VALUES ('$name', {$v[0]}, {$v[1]}, {$v[2]}, {$weightSet[$name]});"; | |
} else { | |
echo "INSERT INTO ".TMP_TABLE." (name, length, width, height) VALUES ('$name', {$v[0]}, {$v[1]}, {$v[2]});"; | |
} | |
echo PHP_EOL; | |
} | |
//make correlated subquery to get only first relation to fit it in. | |
echo PHP_EOL; | |
echo "-- select data (modify query to suit your needs)" . PHP_EOL; | |
$condition = buildCondition("p", "c"); | |
$subQuery = " | |
SELECT | |
id | |
FROM | |
".TMP_TABLE." c | |
WHERE | |
$condition | |
ORDER BY c.id ASC | |
LIMIT 1"; | |
echo "SELECT | |
firstCat.name, count(*) | |
FROM | |
".SRC_TABLE." AS p | |
INNER JOIN ".TMP_TABLE." AS firstCat | |
WHERE | |
firstCat.id = ($subQuery) | |
GROUP BY | |
firstCat.id;"; | |
echo PHP_EOL; | |
echo PHP_EOL; | |
echo "-- clean up temporary table" . PHP_EOL; | |
echo "DROP TABLE ".TMP_TABLE.";"; | |
/// functions | |
function permutations(array $elements) | |
{ | |
if (count($elements) <= 1) { | |
yield $elements; | |
} else { | |
foreach (permutations(array_slice($elements, 1)) as $permutation) { | |
foreach (range(0, count($elements) - 1) as $i) { | |
yield array_merge( | |
array_slice($permutation, 0, $i), | |
[$elements[0]], | |
array_slice($permutation, $i) | |
); | |
} | |
} | |
} | |
} | |
function buildCondition($productAlias, $categoryAlias) | |
{ | |
$dimensions = ["$categoryAlias.length", "$categoryAlias.width", "$categoryAlias.height"]; | |
$permutations = permutations($dimensions); | |
$parts = []; | |
foreach ($permutations as $v) { | |
$parts [] = "($productAlias.".COL_LENGTH." <= {$v[0]} AND $productAlias.".COL_WIDTH." <= {$v[1]} AND $productAlias.".COL_HEIGHT." <= {$v[2]})" . PHP_EOL; | |
} | |
$c = "-- dimensions condition" . PHP_EOL; | |
$c .= " (" . trim(implode(" OR ", $parts)) . ")" . PHP_EOL; | |
$c .= " -- weight condition" . PHP_EOL; | |
$c .= " AND (c.weight IS NULL OR p.weight <= c.weight)"; | |
return $c; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment