2011-08-05 18 views
0

我有一個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(日期)等各種組合,但我似乎無法找出一種方法來有效地做到這一點。

我一直能夠得到這個工作的唯一方法是對用戶表,w/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

也許這有助於http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/ – cristian

+0

感謝您的鏈接......將它添加到我的instapaper列表中以供稍後閱讀。 – Travis

回答

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 
+0

謝謝....那個查詢花費了18秒....完美!!! – Travis

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) 

編輯請把這個作爲查詢的建議......

與用戶的這種量「加盟」可能會更快數百次,然後兩個SELECT子查詢

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標識第一個日期和最後一個日期行,並且主查詢將再次獲取行以獲取所有數據。

+0

謝謝,我會試一試。 – Travis

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); 
+0

羅蘭多,我不能保證第一個id始終與第一次約會相匹配。用戶可以指定一天,例如,如果他們沒有在一週內記錄測量結果,但需要返回並添加一個測量結果。 – Travis

相關問題