将多条记录合并成一行
Merge multiple records in single row
我试图让两条单独的记录显示在一行上,但不断收到多行空值。我想,如果我按 Test_Date 分组,我就可以在每个测试日期得到一行,分数在一行上,但正如你所看到的,这对我来说行不通。
如何将这两行合并为一行,在阅读分数旁边显示数学分数?
SELECT st.test_date, t.name, decode(ts.name,'Mathematics', sts.numscore) as Mathematics,
decode(ts.name, 'Reading', sts.numscore) as Reading
FROM studenttestscore sts
JOIN studenttest st ON sts.studenttestid = st.id
JOIN testscore ts ON sts.testscoreid = ts.id
JOIN test t on ts.testid = t.id
JOIN students s ON s.id = st.studentid
WHERE t.id IN (601, 602, 603)
AND s.student_number = '108156'
GROUP BY st.test_date, t.name,
decode(ts.name,'Mathematics', sts.numscore),
decode(ts.name, 'Reading', sts.numscore)
ORDER BY st.test_date
--- CURRENT OUTPUT ---
Test_Date Name Mathematics Reading
29-AUG-13 MAP FALL 227 (null)
29-AUG-13 MAP FALL (null) 213
22-JAN-14 MAP WINTER 231 (null)
22-JAN-14 MAP WINTER (null) 229
05-MAY-14 MAP SPRING 238 (null)
05-MAY-14 MAP SPRING (null) 233
--- DESIRED OUTPUT ---
Test_Date Name Mathematics Reading
29-AUG-13 MAP FALL 227 213
22-JAN-14 MAP WINTER 231 229
05-MAY-14 MAP SPRING 238 233
您似乎希望日期和姓名同名,所以只将它们包含在 GROUP BY
中。其余使用聚合函数:
SELECT st.test_date, t.name,
MAX(CASE WHEN ts.name = 'Mathematics' THEN sts.numscore END) as Mathematics,
MAX(CASE WHEN ts.name = 'Reading' THEN sts.numscore END) as Reading
FROM studenttestscore sts JOIN
studenttest st
ON sts.studenttestid = st.id JOIN
testscore ts
ON sts.testscoreid = ts.id JOIN
test t
ON ts.testid = t.id JOIN
students s
ON s.id = st.studentid
WHERE t.id IN (601, 602, 603) AND s.student_number = '108156'
GROUP BY st.test_date, t.name,
ORDER BY st.test_date;
我还将 decode()
替换为 CASE
,这是在表达式中表达条件的 ANSI 标准形式。
您必须使用 Aggergate MAX()
并按名称和测试日期分组才能获得所需的结果
select t.test_date,
t.name, max(Mathematics) as Mathematics,
max(Reading) as Reading
from t
GROUP BY t.test_date, t.name
ORDER BY t.test_date;
我试图让两条单独的记录显示在一行上,但不断收到多行空值。我想,如果我按 Test_Date 分组,我就可以在每个测试日期得到一行,分数在一行上,但正如你所看到的,这对我来说行不通。
如何将这两行合并为一行,在阅读分数旁边显示数学分数?
SELECT st.test_date, t.name, decode(ts.name,'Mathematics', sts.numscore) as Mathematics,
decode(ts.name, 'Reading', sts.numscore) as Reading
FROM studenttestscore sts
JOIN studenttest st ON sts.studenttestid = st.id
JOIN testscore ts ON sts.testscoreid = ts.id
JOIN test t on ts.testid = t.id
JOIN students s ON s.id = st.studentid
WHERE t.id IN (601, 602, 603)
AND s.student_number = '108156'
GROUP BY st.test_date, t.name,
decode(ts.name,'Mathematics', sts.numscore),
decode(ts.name, 'Reading', sts.numscore)
ORDER BY st.test_date
--- CURRENT OUTPUT ---
Test_Date Name Mathematics Reading
29-AUG-13 MAP FALL 227 (null)
29-AUG-13 MAP FALL (null) 213
22-JAN-14 MAP WINTER 231 (null)
22-JAN-14 MAP WINTER (null) 229
05-MAY-14 MAP SPRING 238 (null)
05-MAY-14 MAP SPRING (null) 233
--- DESIRED OUTPUT ---
Test_Date Name Mathematics Reading
29-AUG-13 MAP FALL 227 213
22-JAN-14 MAP WINTER 231 229
05-MAY-14 MAP SPRING 238 233
您似乎希望日期和姓名同名,所以只将它们包含在 GROUP BY
中。其余使用聚合函数:
SELECT st.test_date, t.name,
MAX(CASE WHEN ts.name = 'Mathematics' THEN sts.numscore END) as Mathematics,
MAX(CASE WHEN ts.name = 'Reading' THEN sts.numscore END) as Reading
FROM studenttestscore sts JOIN
studenttest st
ON sts.studenttestid = st.id JOIN
testscore ts
ON sts.testscoreid = ts.id JOIN
test t
ON ts.testid = t.id JOIN
students s
ON s.id = st.studentid
WHERE t.id IN (601, 602, 603) AND s.student_number = '108156'
GROUP BY st.test_date, t.name,
ORDER BY st.test_date;
我还将 decode()
替换为 CASE
,这是在表达式中表达条件的 ANSI 标准形式。
您必须使用 Aggergate MAX()
并按名称和测试日期分组才能获得所需的结果
select t.test_date,
t.name, max(Mathematics) as Mathematics,
max(Reading) as Reading
from t
GROUP BY t.test_date, t.name
ORDER BY t.test_date;