我正在寻找如何选择最便宜的JOIN 行。因为ON子句响应多个行。
默认情况下,MySQL采用它找到的第一行,我无法对其采取行动。
SELECT g.id
, g.name
, p.description
, x.annually
FROM tblproductgroups g
JOIN tblproducts p
ON p.gid = g.id
AND p.hidden = 0
JOIN tblpricing x
ON x.relid = p.id
WHERE g.hidden = 0
AND g.id in (1,2,3)
AND x.type = 'product'
GROUP
BY g.id
我必须修改这种tblpricing的JOIN,但是该列的任何比较操作"每年"给我一个错误。
编辑:样本
CREATE TABLE `tblproductgroups` (
`id` int(10) NOT NULL,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`hidden` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tblproductgroups` (`id`, `name`, `hidden`) VALUES
(1, 'Hébergement WEB', 0),
(2, 'Serveurs virtuels KVM', 0),
(3, 'Serveurs dédiés Pro', 0),
(5, 'Colocation', 0);
CREATE TABLE `tblproducts` (
`id` int(10) NOT NULL,
`gid` int(10) NOT NULL,
`name` text COLLATE utf8_unicode_ci NOT NULL,
`description` text COLLATE utf8_unicode_ci NOT NULL,
`hidden` tinyint(1) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tblproducts` (`id`, `gid`, `name`, `description`, `hidden`) VALUES
(1, 1, 'Web Basic 2018', 'blablabla', 0),
(2, 1, 'Web Classic 2018', 'blablabla', 0),
(3, 1, 'Web Advanced 2018', 'blablabla', 0),
(5, 2, 'VPS Basic', 'blablabla', 0),
(6, 2, 'VPS Classic', 'blablabla', 0),
(7, 2, 'VPS Advanced', 'blablabla', 0),
(8, 3, 'SD-S 2018', 'blablabla', 0),
(9, 3, 'SD-L 2016', 'blablabla', 1),
(10, 3, 'SD-M 2018', 'blablabla', 0),
(11, 3, 'SD-XL 2018', 'blablabla', 0);
CREATE TABLE `tblpricing` (
`id` int(10) NOT NULL,
`type` enum('product','addon') COLLATE utf8_unicode_ci NOT NULL,
`relid` int(10) NOT NULL,
`annually` decimal(10,2) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `tblpricing` (`id`, `type`, `relid`, `annually`) VALUES
(1, 'product', 1, '30'),
(39, 'product', 2, '20'),
(40, 'product', 3, '10'),
(42, 'product', 5, '100'),
(43, 'product', 6, '50'),
(44, 'product', 7, '25'),
(45, 'product', 8, '2000'),
(46, 'product', 9, '1000'),
(47, 'product', 9, '500'),
(48, 'product', 10, '250');
我的查询结果是:
1 Hébergement WEB blablabla 30.00
2 Serveurs virtuels KVM blablabla 100.00
3 Serveurs dédiés Pro blablabla 2000.00
正确的结果是:
1 Hébergement WEB blablabla 10.00
2 Serveurs virtuels KVM blablabla 25.00
3 Serveurs dédiés Pro blablabla 250.00
答案 0 :(得分:1)
...粗略地
SELECT a.*
FROM
( SELECT g.id
, g.name
, p.description
, x.annually
FROM tblproductgroups g
JOIN tblproducts p
ON p.gid = g.id
AND p.hidden = 0
JOIN tblpricing x
ON x.relid = p.id
WHERE g.hidden = 0
AND g.id in (1,2,3)
AND x.type = 'product'
) a
JOIN
( SELECT id
, MIN(annually) annually
FROM
( SELECT g.id
, g.name
, p.description
, x.annually
FROM tblproductgroups g
JOIN tblproducts p
ON p.gid = g.id
AND p.hidden = 0
JOIN tblpricing x
ON x.relid = p.id
WHERE g.hidden = 0
AND g.id in (1,2,3)
AND x.type = 'product'
) x
GROUP
BY id
) b
ON b.id = a.id
AND b.annually = a.annually
答案 1 :(得分:0)
这应该这样做:
SELECT g.id
, g.name
, p.name
, x.annually
FROM tblproductgroups g
JOIN tblproducts p
ON p.gid = g.id
AND p.hidden = 0
JOIN tblpricing x
ON x.relid = p.id
/* Subtable containing the minimum annual fee per group */
JOIN (SELECT subg.id, MIN(subx.annually) AS annually FROM tblproductgroups subg
INNER JOIN tblproducts subp On subg.id = subp.gid
AND subp.hidden = 0
INNER JOIN tblpricing subx ON subx.relid = subp.id
WHERE subg.hidden = 0
AND subg.id in (1,2,3)
AND subx.type = 'product'
GROUP BY subg.id) m
ON g.id = m.id AND x.annually = m.annually
WHERE g.hidden = 0
AND g.id in (1,2,3)
AND x.type = 'product'
如果您实际上没有在列定义中使用任何聚合函数,请不要使用GROUP BY
。除非你确切知道自己在做什么,否则它可能适用于MySQL the results will be unpredictable。