【发布时间】:2017-03-18 20:20:54
【问题描述】:
数据
假设我有一个应用程序,我正在测试汽车的速度、性能、安全性等。 我有一组数据格式如下:
CAR TABLE
ID CAR_NAME
1 Ford Focus 2006
2 Toyota Corolla 2014
5 Tesla Model S 2016
TEST TABLE
ID TEST_NAME
1 acceleration
2 topSpeed
3 zeroToSixty
4 smoothRide
5 seating
6 ergonomics
7 handling
8 breaking
9 audio
TEST_CATEGORY TABLE
ID CATEGORY_NAME
1 Speed
2 Performance
3 Comfort
4 Safety
TEST_PLAN TABLE
ID CAR_ID CATEGORY_ID TEST_ID
1 1 1 1
2 1 1 2
3 1 1 3
4 1 2 1
5 1 2 3
6 1 2 8
7 1 2 7
8 1 4 8
9 1 4 5
11 5 1 1
12 5 1 2
13 5 1 3
14 5 1 7
15 5 2 1
16 5 2 7
17 5 2 4
18 5 3 4
19 5 3 5
TEST_INSTANCE TABLE
ID CAR_ID TEST_ID CATEGORY_ID GRADE TEST_DATE
1 1 1 1 C 2015-03-14
2 1 1 1 C 2015-03-17
3 1 1 2 D 2015-03-15
4 1 1 2 C 2015-03-16
5 1 1 2 B 2015-03-17
6 1 3 1 B 2015-03-14
7 1 3 1 C 2015-03-16
8 1 8 2 C 2015-03-13
9 5 1 1 B 2015-03-15
10 5 1 1 B 2015-03-17
11 5 1 2 A 2015-03-19
12 5 1 2 A 2015-03-12
13 5 7 2 B 2015-03-14
14 5 7 2 B 2015-03-16
15 5 7 2 A 2015-03-18
16 5 7 2 B 2015-03-15
17 5 9 5 A 2015-03-14 --note that this test is not part of the test plan
所以有 5 个表,但只有最后两个(TEST_PLAN、TEST_INSTANCE)很重要。其余的只是 JOIN 依赖项。
TEST_PLAN 表
TEST_PLAN 表定义了需要针对每辆汽车进行的一系列测试。每个测试可以属于多个类别。 TEST_PLAN 表显示需要进行哪些测试以及属于什么类别。速度类别下的加速度测试,不计入性能下的加速度测试。
The test plans look a bit like this:
Ford Focus 2006
Speed
acceleration
topSpeed
zeroToSixty
Performance
acceleration
zeroToSixty
breaking
handling
Safety
breaking
seating
Tesla Model S 2016
Speed
acceleration
topSpeed
zeroToSixty
handling
Performance
acceleration
handling
smoothRide
Comfort
smoothRide
seating
TEST_INSTANCE 表
TEST_INSTANCE 表跟踪已进行了哪些测试(在哪个类别下)以及何时进行。给定的测试类别可能已经对给定的汽车进行了不止一次。也可能已经进行了没有测试计划的测试。
The TEST_INSTANCE table (all JOINed up) looks like this:
ID CAR TEST_NAME TEST_CATEGORY GRADE TEST_DATE
1 Ford Focus 2006 acceleration Speed C 2015-03-14
2 Ford Focus 2006 acceleration Speed C 2015-03-17
3 Ford Focus 2006 acceleration Performance D 2015-03-15
4 Ford Focus 2006 acceleration Performance C 2015-03-16
5 Ford Focus 2006 acceleration Performance B 2015-03-17
6 Ford Focus 2006 zeroToSixty Speed B 2015-03-14
7 Ford Focus 2006 zeroToSixty Speed C 2015-03-16
8 Ford Focus 2006 breaking Performance C 2015-03-13
9 Tesla Model S 2016 acceleration Speed B 2015-03-17
10 Tesla Model S 2016 acceleration Speed B 2015-03-15
11 Tesla Model S 2016 acceleration Performance A 2015-03-16
12 Tesla Model S 2016 acceleration Performance A 2015-03-14
13 Tesla Model S 2016 handling Performance B 2015-03-19
14 Tesla Model S 2016 handling Performance B 2015-03-12
15 Tesla Model S 2016 handling Performance A 2015-03-13
16 Tesla Model S 2016 handling Performance B 2015-03-18
17 Tesla Model S 2016 zeroToSisty Speed A 2015-03-14 --note that this test is not part of the test plan
我想做的事
我需要做几件涉及聚合的事情。我正在尝试获取给定测试计划中所有测试的列表(针对单个汽车)并加入来自测试实例的以下内容:
给定测试在给定类别中首次运行的日期。
在某个类别中运行给定测试的最近日期。
在给定类别中运行测试的总次数。
给定测试类别的最差结果
给定测试类别的最新结果。
我正在使用以下查询,并且我已经弄清楚如何获得 1-4。我在 5 上仍然遇到问题:
SELECT
tp.id,
c.car_name
tc.category_name,
t.test_name,
MIN(ti.test_date) as firstRun, -- this grabs the date of the first time the test-category ran
MAX(ti.test_date) as latest, -- this grabs the latest date the test-category ran
MIN(ti.grade) as worst, -- this grabs the worst result fron the test-category
COUNT(ti.test_date) as testRuns, -- this grabs the total number of tests run from the category.
ti.grade as latestGrade -- this seems to give me the most recent grade from a test-category, but I can't be sure.
FROM
testPlan tp
LEFT JOIN car c ON c.id = tp.car_id
LEFT JOIN test_category tc ON tc.id = tp.category_id
LEFT JOIN test t ON t.id = tp.test_id
LEFT JOIN test_instance ti ON (
ti.car_id = tp.car_id
AND ti.category_id = tp.category_id
AND ti.test_id = tp.test_id
)
WHERE
tp.car_id = 5
GROUP BY
tp.id;
对于第 5 项,ti.grade as latestGrade 似乎为我提供了给定测试类别的最新成绩,但我无法确定这一点。我想我需要某种ORDER BY 来确定。
预期结果
The final query should return something like this:
ID CAR TEST_CATEGORY TEST_NAME FIRST_RUN LATEST TESTS_RUN LATEST_GRADE WORST_GRADE
11 Tesla Model S Speed acceleration 2015-03-15 2015-03-17 2 B B
12 Tesla Model S Speed topSpeed NULL NULL 0 NULL NULL
13 Tesla Model S Speed zeroToSixty NULL NULL 0 NULL NULL
14 Tesla Model S Speed handling NULL NULL 0 NULL NULL
15 Tesla Model S Performance acceleration 2015-03-14 2015-03-16 2 A A
16 Tesla Model S Performance handling 2015-03-12 2015-03-19 4 A B
17 Tesla Model S Performance smoothRide NULL NULL 0 NULL NULL
18 Tesla Model S Comfort smoothRide NULL NULL 0 NULL NULL
19 Tesla Model S Comfort seating NULL NULL 0 NULL NULL
Resultset Note:
- there should be only one row per each test-category in the test plan (per car). (9 items in Tesla S test plan).
问题
- 我需要在查询中添加什么以确保 latestGrade 始终是最新的?
-
UNION ALL在加入非计划结果时会导致性能下降吗? (我的真实数据集是返回的 10k+ 条记录)。有没有办法重构我的查询,使其不需要UNION ALL?
【问题讨论】:
-
按年级从 my_table 组中选择 GRADE ,Max(TEST_DATE)
-
@Strawberry... 不是 100% 我明白。您是否建议简单地将
GROUP BY grade添加到我的GROUP BY?我的结果集每个测试计划条目应该有一行。添加组依据使其拥有更多。 -
1-4 可以使用按类别分组的简单
MIN()和MAX()完成。 5 需要加入类似stackoverflow.com/questions/7745609/… 中的查询。
标签: mysql join aggregate-functions