哪个MySQL查询选择基于位置的产品

时间:2014-04-15 22:05:44

标签: php mysql sql database

基本情景:我有3种类型的产品,几种制造商,并根据客户的位置,产品来自最近的制造商。我有一些几乎可以工作的东西,但我认为我的桌子需要结构更好一点。

以下是我目前的情况:

CREATE TABLE IF NOT EXISTS `mfr` (
  `id` int(11) NOT NULL auto_increment,
  `zip_code` int(5) NOT NULL,
  `radius` int(5) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

INSERT INTO `mfr` (`id`, `zip_code`, `radius`) VALUES
(1, 72756, 500),
(2, 74030, 360),
(3, 74701, 325),
(4, 72947, 300),
(5, 73112, 40),
(6, 63077, 100),
(7, 63106, 75);

CREATE TABLE IF NOT EXISTS `models` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `mfr_id` int(5) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;

INSERT INTO `models` (`id`, `name`, `mfr_id`) VALUES
(1, 'model 1', 1),
(2, 'model 2', 2),
(3, 'model 3', 2),
(4, 'model 1', 6),
(5, 'model 2', 4),
(6, 'model 3', 4);

CREATE TABLE IF NOT EXISTS `distances` (
  `id` int(11) NOT NULL auto_increment,
  `time_inserted` int(11) NOT NULL,
  `zip_code` int(5) NOT NULL,
  `mfr_id` int(5) NOT NULL,
  `miles` int(5) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `zip_code` (`zip_code`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=16 ;

INSERT INTO `distances` (`id`, `time_inserted`, `zip_code`, `mfr_id`, `miles`) VALUES
(1, 1397522155, 72761, 1, 41),
(2, 1397522155, 72761, 2, 131),
(3, 1397522155, 72761, 3, 223),
(5, 1397522155, 72761, 5, 197),
(6, 1397522156, 72761, 6, 301),
(7, 1397522156, 72761, 7, 353),
(8, 1397522166, 72761, 4, 87);

预期成果: 邮编72761应该返回模型1的mfr_id为1(41英里),mfr_id为4(模型2)和3(英里数为87),而模型2和3的mfr_id为2,即使milage为131,大于87。

http://www.sqlfiddle.com/#!2/e450b/1/0

1 个答案:

答案 0 :(得分:0)

试试这个:

SELECT
  m.name,
  d.miles,
  d.mfr_id
FROM distances d
  JOIN mfr ON mfr.id = d.mfr_id
    AND mfr.radius > d.miles
  JOIN models m ON m.mfr_id = mfr.id
-- get min miles per model
  JOIN (SELECT m1.name,min(d1.miles) miles
        FROM models m1
          JOIN distances d1 ON d1.mfr_id = m1.mfr_id
        GROUP BY m1.name
        ) md ON md.name = m.name
             AND md.miles = d.miles
WHERE d.zip_code = 72761
ORDER BY d.miles ASC