我的表:
id,user_id,street,street_number,street_stairs,street_door,zip,place,country,type
Id是主键。 类型可以是0或1。 每个user_id都可以有多个地址行。
CREATE TABLE `user_address_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`street` varchar(55) NOT NULL,
`street_number` varchar(5) NOT NULL,
`street_stairs` varchar(3) DEFAULT NULL,
`street_door` varchar(3) DEFAULT NULL,
`zip` varchar(10) NOT NULL,
`place` varchar(30) NOT NULL,
`country` varchar(2) NOT NULL,
`type` tinyint(2) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `user_id` (`user_id`,`street`,`street_number`,`street_stairs`,`street_door`,`zip`,`place`,`country`)
) ENGINE=MyISAM AUTO_INCREMENT=192 DEFAULT CHARSET=utf8
查询:
SELECT `t0`.`user_id`, `t0`.`country`
FROM `user_address_data` as `t0`
INNER JOIN (SELECT `t1`.`user_id`, MAX(`t1`.`id`) as `id`
FROM `user_address_data` as `t1`
RIGHT JOIN (SELECT `user_address_data`.`user_id`, MAX(`user_address_data`.`type`) as `type`
FROM `user_address_data`
WHERE `user_address_data`.`user_id` IN (42,4, 20, 41, 43, 171)
GROUP BY `user_address_data`.`user_id`) as `t2`
ON `t2`.`user_id` = `t1`.`user_id` && `t2`.`type` = `t1`.`type`
GROUP BY `t1`.`user_id`) as `t3`
ON `t3`.`id` = `t0`.`id`
问题:正如您所看到的,我正在尝试从地址表中获取最新的行。但是我需要最新行,其中“类型”字段代表 user_id 的最大类型。
我的想法是先为每个user_id选择max(type)。因此我能够选择每个用户的max(id)。现在我可以从字段国家/地区中选择相应的国家/地区代码。
它有效,但我不认为它有效。必须创建2个临时表。有没有其他方法可以更有效地做到这一点?
感谢。
按要求,EXPLAIN SELECT:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 6
1 PRIMARY t0 eq_ref PRIMARY PRIMARY 4 t3.id 1
2 DERIVED <derived3> ALL NULL NULL NULL NULL 6 Using temporary; Using filesort
2 DERIVED t1 ref user_id user_id 4 t2.user_id 11
3 DERIVED user_address_data range user_id user_id 4 NULL 20 Using where
答案 0 :(得分:0)
我不知道你是否会在地址类型的数据中得到意外的“类型”....我不知道地址“类型”代表什么。针对单个用户采用以下方案。
User Address ID Type of Address
1 1 8
1 2 3
1 3 1
1 4 0
如果您获得最大地址ID(在本例中为4),并且地址的最大类型(地址ID = 1中的8),则可能导致数据不正确。也就是说,如果主要考虑的是最新的地址ID,那么你永远不需要关心max()类型的地址,因为只有一条记录与max(地址ID)相关联......所以,如果你想要基于最高类型地址的最后一个地址ID,我会选择你所描述的两个子查询(导致地址ID = 1,Type = 8)。但是如果你正在寻找(地址= 4,Type = 0,因为这是一个人的最新地址,我会修改它)。
告诉我们。
选择