Home > Software design >  Missing row when using mysql max function
Missing row when using mysql max function

Time:02-26

I have the following table below. I'm trying to retrieve data and group them by name, I then want only the latest row according to the created_at column. I ran the query below and seem to get getting what I want. However, when I add more weights, the query sometimes omits the some data. What is going on???

 "id"   "name"                  "value" "created_at"    "animal_id"
    "6"     "body_condition_score"  "9" "2022-02-26"       "1"
    "9"     "body_condition_score"  "8" "2022-02-27"      "1"
    "7"     "dental_score"          "4" "2022-02-25"       "1"
    "10"    "dental_score"          "1" "2022-03-25"       "1"
    "11"    "dental_score"          "5" "2022-03-25"       "2"
    "4"     "heart_rate"           "1500""2022-02-25"      "1"
    "5"     "respiratory_rate"      "20"    "2022-02-25"    "1"
    "2"     "weight"              "90.52"   "2022-02-22"    "1"
    "3"     "weight"               "99"     "2022-02-23"    "1"
    "13"    "weight"               "0"  "2022-02-21"        "1"
    "12"    "weight"              "1"   "2022-02-25"        "2"



    SELECT vitals.* 
FROM    vitals
INNER JOIN  
( 
    SELECT `name`, `value`, MAX(created_at) created_at
    FROM vitals
    GROUP BY `name`
) grouped 
ON grouped.`name` = vitals.`name` 
AND grouped.created_at = vitals.created_at  
WHERE animal_id = 1

"id" "name"                  "value"    "created_at"    "animal_id"
"4"  "heart_rate"            "1500" "2022-02-25"    "1"
"5"  "respiratory_rate"      "20"   "2022-02-25"    "1"
"9"  "body_condition_score"  "8"    "2022-02-27"    "1"
"10"  "dental_score"         "1"    "2022-03-25"    "1"

CodePudding user response:

whats the value of animal_id for your last data? if you add "weight" for animal_id = 2 and have the max created_at then your query will return no row for "weight"

because:

  1. in subquery "grouped" not use "when animal_id = 1" then it is possible query return max created_at in animal_id = 2
  2. you use inner join and "when animal_id = 1" on main query, so when sub query return created_at with animal_id = 2 they will not link.

my suggest: if you want to select only animal_id = 1, change your sub query to

INNER JOIN  
( 
    SELECT `name`, `value`, MAX(created_at) created_at
    FROM vitals
    WHERE animal_id = 1
    GROUP BY `name`
) grouped 

if you does not care about animal_id, remove when animal_id = 1

SELECT vitals.* 
FROM    vitals
INNER JOIN  
( 
    SELECT `name`, `value`, MAX(created_at) created_at
    FROM vitals
    GROUP BY `name`
) grouped 
ON grouped.`name` = vitals.`name` 
AND grouped.created_at = vitals.created_at  

CodePudding user response:

If you have MySQL 8 version you could use:

with cte as (
             select *,ROW_NUMBER() OVER ( partition by name ORDER BY created_at desc ) row_num
             from vitals where animal_id=1
)
select id,name,value,created_at,animal_id 
from cte 
where row_num=1;

If you have older version which doesn't support windows function try:

SELECT v.id,v.name,v.value,v.created_at,v.animal_id
FROM vitals v
INNER JOIN (
    SELECT name,animal_id, MAX(created_at) as created_at
    FROM vitals
    where animal_id=1
    GROUP BY name,animal_id
           ) v1 ON v.name = v1.name AND v.created_at = v1.created_at
where v.animal_id=1;  

Demo

  • Related