架构:
CREATE TABLE `product` (
`product_id` int(11) NOT NULL AUTO_INCREMENT,
`sort_order` int(11) NOT NULL DEFAULT '0',
`status` tinyint(1) NOT NULL DEFAULT '0',
PRIMARY KEY (`product_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
insert into product (sort_order, status)
values
(0, 1),
(0, 1),
(0, 1),
(0, 1),
(0, 1);
CREATE TABLE `product_description` (
`product_id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`product_id`),
KEY `name` (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
insert into product_description
values
(1, 'product_1'),
(2, 'product_2'),
(3, 'product_3'),
(4, 'product_4'),
(5, 'product_5');
CREATE TABLE `product_to_category` (
`product_id` int(11) NOT NULL,
`product_category_id` int(11) NOT NULL,
PRIMARY KEY (`product_id`,`product_category_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
insert into product_to_category
values
(1, 1),
(2, 1),
(3, 1),
(4, 1),
(5, 1);
CREATE TABLE `product_category_path` (
`product_category_id` int(11) NOT NULL,
`path_id` int(11) NOT NULL,
`level` int(11) NOT NULL,
PRIMARY KEY (`product_category_id`,`path_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
insert into product_category_path values (1, 1, 0);
查询:
SELECT p.product_id, pc.product_category_id, pd.name
FROM `product` p
LEFT JOIN `product_description` pd ON pd.product_id = p.product_id
LEFT JOIN `product_to_category` pc ON pc.product_id = p.product_id
WHERE p.status = 1 AND pc.product_category_id IN (SELECT product_category_id FROM `product_category_path` WHERE path_id = 1)
ORDER BY p.sort_order ASC;
在localhost和托管结果总是相同的:1,2,3,4,5。但在托管它显示1,3,2,5,4或2,1,5,3,4和每次新订购。为什么呢?
更新
http://dev.mysql.com/doc/refman/5.5/en/order-by-optimization.html
答案 0 :(得分:2)
允许SQL系统(任何品牌和型号)以他们认为方便的任何顺序返回结果集行,除非您专门指定订单。换句话说,除非在ORDER BY
中指定,否则结果集的顺序正式无法预测。换句话说,在localhost
服务器上,您的结果按照您认为应该处于的顺序完全是偶然的。表没有固有的顺序。
您真的很幸运,您的生产服务器如此迅速地在您的查询中暴露了这个缺陷。开发人员通常不会发现这些东西,直到他们的表格增长到数万行。
由于您的查询修改显示(http://sqlfiddle.com/#!2/211536/2/0),因此结果集中的所有行都具有相同的SORT_ORDER
值。
<强>查询强>:
SELECT p.sort_order, p.product_id, pc.product_category_id, pd.name
FROM `product` p
LEFT JOIN `product_description` pd ON pd.product_id = p.product_id
LEFT JOIN `product_to_category` pc ON pc.product_id = p.product_id
WHERE p.status = 1 AND pc.product_category_id IN (SELECT product_category_id FROM `product_category_path` WHERE path_id = 1)
ORDER BY p.sort_order ASC
<强>结果:
| SORT_ORDER | PRODUCT_ID | PRODUCT_CATEGORY_ID | NAME |
|------------|------------|---------------------|-----------|
| 0 | 1 | 1 | product_1 |
| 0 | 2 | 1 | product_2 |
| 0 | 3 | 1 | product_3 |
| 0 | 4 | 1 | product_4 |
| 0 | 5 | 1 | product_5 |
你已经告诉SQL以这种方式订购它们。两台服务器都这样做了。
如果您需要PRODUCT_ID
以及SORT_ORDER
订购它们,请指定它(http://sqlfiddle.com/#!2/211536/4/0)。
ORDER BY p.sort_order ASC, p.product_id ASC;