Lets say I have 2 tables like so:
MyTable1:
Name ID Timestamp TestNum Grade
Alex 1101 2020-10-01 12:00:00 1 85
Alex 1101 2020-10-02 13:00:00 2 90
Alex 1101 2020-10-03 8:00:00 3 95
Alex 1101 2020-10-04 10:00:00 4 90
MyTable2:
ID Avg StDev
1101 90 4.08
I am trying to get the row of the first (Timestamp) instance where the grade was X standard deviations away.
ExpectedResults:
Name ID Timestamp TestNum StDevsAway
Alex 1101 2020-10-01 12:00:00 1 -1.23
Alex 1101 2020-10-02 13:00:00 2 0
Alex 1101 2020-10-03 8:00:00 3 1.23
The 4th row should not be returned as its Standard Deviations Away was already found at a previous Timestamp.
I'm still fairly new to MySQL, but this is where I'm at so far:
select a.Name
, a.ID
, a.Timestamp
, a.TestNum
, round( ( a.Grade - b.Avg ) / b.StDev, 2 ) as StDevsAway
from MyTable1 as a
join MyTable2 as b
on a.ID = b.ID
group
by round( ( a.Grade - b.Avg ) / b.StDev, 2 );
I think the question is just about finding "first" row for each id/grade tupe. So (asssuming MySQL 8.0):
select t1.*
from (
select t1.*, row_number() over(partition by id, grade order by timestamp) rn
from mytable1 t1
) t1
where rn = 1
Then, you can bring the second table with a join if you like:
select t1.*, round(t1.grade - t2.avg) / t2.stdev, 2) stdevsaway
from (
select t1.*, row_number() over(partition by id, grade order by timestamp) rn
from mytable1 t1
) t1
inner join mytable2 t2 on t2.id = t1.id
where rn = 1
In earlier versions, you can filter with a subquery:
select t1.*, round(t1.grade - t2.avg) / t2.stdev, 2) stdevsaway
from mytable1 t1
inner join mytable2 t2 on t2.id = t1.id
where t1.timestamp = (
select min(t11.timestamp) from mytable1 t11 where t11.id = t1.id and t11.grade = t1.grade
)
In previous Versin and of Course in mysql8 as well you can do this.
this will exclude every testnum, that gas standard deviation,except the first one, for that user
Schema (MySQL v5.5)
CREATE TABLE MyTable1 (
`Name` VARCHAR(4),
`ID` INTEGER,
`Timestamp` DATETIME,
`TestNum` VARCHAR(7),
`Grade` INTEGER
);
INSERT INTO MyTable1
(`Name`, `ID`, `Timestamp`, `TestNum`, `Grade`)
VALUES
('Alex', '1101', '2020-10-01 12:00:00', '1', '85'),
('Alex', '1101', '2020-10-02 13:00:00', '2', '90'),
('Alex', '1101', '2020-10-03 08:00:00', '3','95'),
('Alex', '1101', '2020-10-04 10:00:00', '4', '90');
CREATE TABLE MyTable2 (
`ID` INTEGER,
`Avg` INTEGER,
`StDev` FLOAT
);
INSERT INTO MyTable2
(`ID`, `Avg`, `StDev`)
VALUES
('1101', '90', '4.08');
Query #1
select
a.Name
, a.ID
, a.Timestamp
, a.TestNum
, round( ( a.Grade - b.Avg ) / b.StDev, 2 ) as StDevsAway
from MyTable1 as a join MyTable2 as b on a.ID = b.ID
WHERE
TestNum NOT IN (SELECT TestNum
FROM MyTable1 c
WHERE c.`ID` = a.`ID`
AND c.`Grade` = b.Avg
AND c.`TestNum`<> (SELECT MIN(TestNum)
FROM MyTable1 d
WHERE d.`ID` = a.`ID`
AND d.`Grade` = b.Avg)
);
| Name | ID | Timestamp | TestNum | StDevsAway |
| ---- | ---- | ------------------- | ------- | ---------- |
| Alex | 1101 | 2020-10-01 12:00:00 | 1 | -1.23 |
| Alex | 1101 | 2020-10-02 13:00:00 | 2 | 0 |
| Alex | 1101 | 2020-10-03 08:00:00 | 3 | 1.23 |
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.