我有一个MYSQL表,其结构如下所示,名为daily_measurements
+------------+----------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | 0 | |
| date | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| weight | float | NO | | 0 | |
| bicep | float | NO | | 0 | |
| chest | float | NO | | 0 | |
| waist | float | NO | | 0 | |
| neck | float | NO | | 0 | |
| thigh | float | NO | | 0 | |
| hips | float | NO | | 0 | |
| shoulders | float | NO | | 0 | |
| knee | float | NO | | 0 | |
| ankle | float | NO | | 0 | |
| created_on | datetime | NO | | 0000-00-00 00:00:00 | |
+------------+----------+------+-----+---------------------+----------------+
我需要检索每个用户第一个和最后一个条目的权重列表。
我尝试了GROUP BY,MIN(日期),MAX(日期)等各种组合,但我似乎无法找到一种有效的方法。
我能够让它工作的唯一方法是在用户表上执行以下查询,带有2个子查询,但由于有大约30,000个用户和>查询的200,000次测量非常糟糕。
SELECT u.id,
(SELECT user_id, weight, date FROM daily_measurements WHERE user_id = u.id ORDER BY date DESC limit 1) as starting_weight,
(SELECT user_id, weight, date FROM daily_measurements WHERE user_id = u.id ORDER BY date ASC limit 1) as ending_weight
FROM users u
任何帮助都将不胜感激。
答案 0 :(得分:1)
我的解决方案:
SELECT
u1.user_id,
u2.first_entry_weight,
u1.weight AS last_entry_weight
FROM daily_measurements u1
INNER JOIN (SELECT
u1.user_id,
u1.weight AS first_entry_weight,
u2.fe,
u2.le
FROM daily_measurements u1
INNER JOIN (SELECT
daily_measurements.user_id,
MIN(date_entry) fe,
MAX(date_entry) le
FROM daily_measurements
GROUP BY daily_measurements.user_id) u2
ON u1.user_id = u2.user_id
AND u1.date_entry = u2.fe) u2
ON u1.user_id = u2.user_id
AND u1.date_entry = u2.le
答案 1 :(得分:0)
目前无法测试它及其性能,但我可以从以下查询开始:
SELECT
u.id,
SUBSTRING_INDEX( GROUP_CONCAT(CAST(d.weight AS CHAR) ORDER BY d.date ASC ), ',', 1 ) as starting_weight,
SUBSTRING_INDEX( GROUP_CONCAT(CAST(d.weight AS CHAR) ORDER BY d.date DESC), ',', 1 ) as ending_weight
FROM users as u
LEFT JOIN daily_measurements as d ON (u.id = d.user_id)
修改请将此视为您的查询建议......
有这么多用户“JOIN”可能比两个SELECT子查询快几百倍
答案 2 :(得分:0)
试试这个:
select tb.* from daily_measurements tb
join (
select user_id, MIN(date) firstDate, MAX(date) lastDate
from daily_measurements
group by user_id
) temp
on tb.user_id = temp.user_id
and (tb.date = temp.firstDate or tb.date = temp.lastDate)
子查询将标识每个user_id的第一个日期和最后日期行,主查询将再次获取行以获取所有数据。
答案 3 :(得分:0)
SELECT A.user_id,
B.weight InitialWeight,
B.`date` InitialDate,
C.weight LatestWeight,
C.`date` LatestDate
FROM
(
SELECT user_id,MIN(id) idmin,MAX(id) idmax
FROM daily_measurements GROUP BY user_id
) A
INNER JOIN daily_measurements B ON (A.user_id=B.user_id AND A.idmin = B.id)
INNER JOIN daily_measurements C ON (A.user_id=C.user_id AND A.idmax = C.id);
请确保您有这样的索引
ALTER TABLE daily_measurements ADD UNIQUE INDEX userid_id_ndx (user_id,id);