Monday, 27 May 2013

MySQL (PHP) customer & supplier geo matching

MySQL (PHP) customer & supplier geo matching

I got the following tables:
CREATE TABLE `companies` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `company` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `company_delivery` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_company` int(11) unsigned NOT NULL,
  `latitude` float(10,6) NOT NULL,
  `longitude` float(10,6) NOT NULL,
  `delivery_radius` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
and
CREATE TABLE `customers` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_delivery_address` int(11) DEFAULT NULL,
  `email` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `customer_addresses` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_customer` int(11) unsigned NOT NULL,
  `latitude` float(10,6) NOT NULL,
  `longitude` float(10,6) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
There is even an article table, but this is a simple customer-article (1:n) relation:
CREATE TABLE `articles` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `id_company` int(11) NOT NULL,
  `title` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Challenge: "List all articles for a given customer (to all his delivery addresses) by suppliers that actually deliver to those locations (=delivery adresses incorporating the delivery radii)"
What is the best way to determine which suppliers are relevant to which customers. Suppliers (=company) may define different delivery ranges (determined by lat/lon and radius --> areas they deliver to) and customers may define multiple drop-off addresses.
They table structures are not yet fixed and may be changed. I am looking for the fastest (and understandable) way to achieve a customer-supplier matching.
What I can currently identify is the suppliers (with a fixed delivery-radius of 25km) relevant for one (1) particular customer address. However customers may have different drop-off points too and suppliers may define different delivery radii:
SELECT
  *,
  ( 3959 * acos( cos( radians(PHP_LAT) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(PHP_LON) ) + sin( radians(PHP_LAT) ) * sin( radians( latitude ) ) ) ) AS distance
FROM
  articles AS a
  LEFT JOIN
    company_delivery AS d
    ON d.id = a.id_company
  LEFT JOIN
    companies AS c
    ON c.id = d.id_company
  HAVING
    distance < 25
  ORDER BY
    distance
(PHP_x are placeholders for PHP variables in the query)
Possibilities are fully open:
Implement some spatial functions (MySQL-based)
Implement PHP or Stored procedures to create a customer-supplier-mapping table
Combination of the above
Thanks for your help and advise on a specific direction to further explore.

No comments:

Post a Comment