查询为每个用户获取第一个输入字段

时间:2011-08-05 22:06:17

标签: mysql

我有一个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

任何帮助都将不胜感激。

4 个答案:

答案 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);