7

(我不会说英语很好,但我会尽力而为)

我有两张桌子。

表格1

身份证用户
---------------------
1 | A001 | 用户1
2 | A002 | 用户1
3 | A003 | 用户2
4 | A002 | 用户3

表2

id carid 日期时间 lat lon
-------------------------------------------------- --
1 | A001 | 2013-25-06 10:00:00 | -23.0000 | -46.0000
2 | A002 | 2013-25-06 10:01:00 | -24.3500 | -45.3200
3 | A002 | 2013-25-06 10:02:00 | -24.3800 | -45.3300
4 | A001 | 2013-25-06 10:05:00 | -23.0500 | -46.1000
5 | A003 | 2013-25-06 10:07:00 | -24.3500 | -45.3200
6 | A001 | 2013-25-06 10:10:00 | -23.0700 | -46.1200

我需要从按日期时间排序的“user1”中选择每个不同的注册表“carid”

结果我需要:

   carid 日期时间 lat lon
--------------------------------------------------
   A001 | 2013-25-06 10:10:00 | -23.0700 |-46.1200
   A002 | 2013-25-06 10:02:00 | -24.3800 |-45.3300

我实际制作的方式是从我想要的用户那里选择所有“carid”,然后通过.net 单独选择每一行。

`SELECT carid FROM table1 where user = “user1”;`
心
-----
A001
A002

然后选择我想要的行:

SELECT * FROM table2 WHERE car_id='A001' ORDER BY datetime DESC limit 1
SELECT * FROM table2 WHERE car_id='A002' ORDER BY datetime DESC limit 1

但是根据该用户的注册表“carid”的数量,我必须做很多查询。我不知道是否可以通过一个 SELECT 改进我正在做的方式来做到这一点,但这就是我尝试过的:

SELECT car_id, datetime, lat, lon from table1 
INNER JOIN table2 on carid = car_id
WHERE user = 'user1'
GROUP BY carid
ORDER BY datetime DESC;

结果:

carid 日期时间 lat lon
-------------------------------------------------- ----
 A002 | 2013-25-06 10:01:00 | -24.3500 | -45.3200
 A001 | 2013-25-06 10:02:00 | -23.0000 | -46.0000

我也试过这个:

SELECT car_id, MAX(datetime) as datetime, lat, lon from table1 
INNER JOIN table2 on carid = car_id
WHERE user = 'user1'
GROUP BY carid
ORDER BY datetime DESC;

结果:

carid 日期时间 lat lon
-------------------------------------------------- ----
 A001 | 2013-25-06 10:10:00 | -23.0000 | -46.0000
 A002 | 2013-25-06 10:02:00 | -24.3500 | -45.3200

但是我得到的结果是错误的。如果不选择所有行,我不知道该怎么办,这比我真正制作的方式要慢。

有什么想法吗?

4

2 回答 2

6

您可以加入table2两次,一次获得max(datetime)for each carId,第二次获得latand与andlon关联:carIddatetime

select t1.carid, t2.datetime, t2.lat, t2.lon
from table1 t1
inner join
(
  -- get the lat/lon associated with each carid and max datetime
  select t2.carid, t2.datetime, t2.lat, t2.lon
  from table2 t2
  inner join
  (
    -- get the max datetime for each carid
    select carid, max(datetime) datetime
    from table2
    group by carid
  ) d
    on t2.carid = d.carid
    and t2.datetime = d.datetime
) t2
  on t1.carid = t2.carid
where user = 'user1';

请参阅SQL Fiddle with Demo

您的查询max()返回错误latlon值,因为您仅按 分组,carid因此 MySQL 可以任意选择选择列表中不在聚合函数或 GROUP BY 中的列的值。这种行为是由于MySQL 对 GROUP BY 的扩展

来自 MySQL 文档:

MySQL 扩展了 GROUP BY 的使用,以便选择列表可以引用未在 GROUP BY 子句中命名的非聚合列。...您可以使用此功能通过避免不必要的列排序和分组来获得更好的性能。但是,这主要在每个未在 GROUP BY 中命名的非聚合列中的所有值对于每个组都相同时很有用。服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,从每个组中选择值不会受到添加 ORDER BY 子句的影响。在选择了值之后对结果集进行排序,并且 ORDER BY 不会影响服务器选择的值。

为了确保返回正确的值,您将需要使用与上述类似的子查询。

于 2013-06-25T15:03:48.297 回答
0

我认为以下查询应该适用于您的场景。我没有尝试过,因为我没有数据。

SELECT
  t1.carid, t2.datetime, t2.lat, t2.lon
FROM
  table1 t1 JOIN table2 t2
  ON t1.carid = t2.carid AND t1.user='user1'
GROUP BY
  carid
HAVING
  t2.datetime=MAX(datetime);

让我知道这个是否奏效。

于 2013-06-25T15:15:53.230 回答