Sql 支点案例我不知道如何进行

Sql 支点案例我不知道如何进行,sql,oracle,Sql,Oracle,使用oracledb。我试图获取一列ts.name中的数据,并将该数据作为列名,将另一列sts.numcore中的数据作为列ts.name的数据。我正在使用案例陈述,但它不起作用。案例语句每行放一个测试分数。我需要把所有的考试成绩都排在一行。任何帮助都将不胜感激。谢谢 SELECT schools.name AS School, s.lastfirst AS Student, s.student_number, s.grade_level, t.name AS Test_Name

使用oracledb。我试图获取一列ts.name中的数据,并将该数据作为列名,将另一列sts.numcore中的数据作为列ts.name的数据。我正在使用案例陈述,但它不起作用。案例语句每行放一个测试分数。我需要把所有的考试成绩都排在一行。任何帮助都将不胜感激。谢谢

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  (case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  (case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  (case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  (case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  (case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date),
  sts.numscore AS Score 
FROM students s,studenttestscore sts,studenttest st,test t,testscore ts,schools
WHERE s.id = sts.studentid
AND sts.studenttestid = st.id
AND sts.testscoreid = ts.id
AND ts.testid = t.id
AND s.schoolid = schools.school_number
AND t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
ORDER BY s.lastfirst,st.test_date DESC

您需要使用如下所示的条件聚合-

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date),
  sts.numscore AS Score 
FROM students s join studenttestscore sts on s.id = sts.studentid
join studenttest st on sts.studenttestid = st.id
join test t on sts.testscoreid = ts.id
join testscore ts on ts.testid = t.id
join schools on s.schoolid = schools.school_number
WHERE t.name = 'ACT' AND sts.numscore > 0 
and s.enroll_status=0 AND s.schoolid=10
group by schools.name,
  s.lastfirst ,
  s.student_number,
  s.grade_level,
  t.name, to_char (st.test_date),sts.numscore
ORDER BY s.lastfirst,st.test_date DESC

您需要使用如下所示的条件聚合-

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date),
  sts.numscore AS Score 
FROM students s join studenttestscore sts on s.id = sts.studentid
join studenttest st on sts.studenttestid = st.id
join test t on sts.testscoreid = ts.id
join testscore ts on ts.testid = t.id
join schools on s.schoolid = schools.school_number
WHERE t.name = 'ACT' AND sts.numscore > 0 
and s.enroll_status=0 AND s.schoolid=10
group by schools.name,
  s.lastfirst ,
  s.student_number,
  s.grade_level,
  t.name, to_char (st.test_date),sts.numscore
ORDER BY s.lastfirst,st.test_date DESC

要在单行中获得结果,需要聚合case表达式的结果;比如:

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date)
FROM students s,studenttestscore sts,studenttest st,test t,testscore ts,schools
WHERE s.id = sts.studentid
AND sts.studenttestid = st.id
AND sts.testscoreid = ts.id
AND ts.testid = t.id
AND s.schoolid = schools.school_number
AND t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
SELECT school, student, student_number, grade_level, test_name,
  act_reading, act_math, act_english, act_science, act_composite,
  to_char(test_date, 'YYYY-MM-DD') AS test_date
FROM (
  SELECT schools.name AS school,
    s.lastfirst AS student,
    s.student_number,
    s.grade_level,
    t.name AS test_name,
    ts.name AS test_score_name,
    sts.numscore,
    st.test_date
  FROM students s
  JOIN studenttestscore sts ON s.id = sts.studentid
  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 schools ON s.schoolid = schools.school_number
  WHERE t.name = 'ACT'
  AND sts.numscore > 0 
  AND s.enroll_status=0
  AND s.schoolid=10
)
PIVOT (
  max(numscore)
  FOR test_score_name IN (
    'ACT_Reading' AS act_reading,
    'ACT_Math' AS act_math,
    'ACT_English' AS act_english,
    'ACT_Science' AS act_science,
    'ACT_Composite' AS act_composite
  )
) p
ORDER BY p.student, p.test_date DESC
在有效地旋转分数时,您不希望将其作为自己的列包含在“选择”列表或“分组依据”中

最好使用现代连接语法,而不是from子句中古老的逗号分隔表列表;您还应该在to_char调用中提供日期的格式模型:

SELECT schools.name AS school,
  s.lastfirst AS student,
  s.student_number,
  s.grade_level,
  t.name AS test_name,
  MAX(CASE WHEN ts.NAME = 'ACT_Reading' THEN sts.numscore END) AS act_reading,
  MAX(CASE WHEN ts.NAME = 'ACT_Math' THEN sts.numscore END) AS act_math,
  MAX(CASE WHEN ts.NAME = 'ACT_English' THEN sts.numscore END) AS act_english,
  MAX(CASE WHEN ts.NAME = 'ACT_Science' THEN sts.numscore END) AS act_science,
  MAX(CASE WHEN ts.NAME = 'ACT_Composite' THEN sts.numscore END) AS act_composite,
  to_char(st.test_date, 'YYYY-MM-DD') AS test_date
FROM students s
JOIN studenttestscore sts ON s.id = sts.studentid
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 schools ON s.schoolid = schools.school_number
WHERE t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
使用pivot的等效方法如下所示:

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date)
FROM students s,studenttestscore sts,studenttest st,test t,testscore ts,schools
WHERE s.id = sts.studentid
AND sts.studenttestid = st.id
AND sts.testscoreid = ts.id
AND ts.testid = t.id
AND s.schoolid = schools.school_number
AND t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
SELECT school, student, student_number, grade_level, test_name,
  act_reading, act_math, act_english, act_science, act_composite,
  to_char(test_date, 'YYYY-MM-DD') AS test_date
FROM (
  SELECT schools.name AS school,
    s.lastfirst AS student,
    s.student_number,
    s.grade_level,
    t.name AS test_name,
    ts.name AS test_score_name,
    sts.numscore,
    st.test_date
  FROM students s
  JOIN studenttestscore sts ON s.id = sts.studentid
  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 schools ON s.schoolid = schools.school_number
  WHERE t.name = 'ACT'
  AND sts.numscore > 0 
  AND s.enroll_status=0
  AND s.schoolid=10
)
PIVOT (
  max(numscore)
  FOR test_score_name IN (
    'ACT_Reading' AS act_reading,
    'ACT_Math' AS act_math,
    'ACT_English' AS act_english,
    'ACT_Science' AS act_science,
    'ACT_Composite' AS act_composite
  )
) p
ORDER BY p.student, p.test_date DESC
但无论如何,它都会转化为聚合/案例版本


当然,所有这些都未经测试,因为我们没有可以使用的模式…

要在一行中获得结果,您需要聚合case表达式的结果;比如:

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date)
FROM students s,studenttestscore sts,studenttest st,test t,testscore ts,schools
WHERE s.id = sts.studentid
AND sts.studenttestid = st.id
AND sts.testscoreid = ts.id
AND ts.testid = t.id
AND s.schoolid = schools.school_number
AND t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
SELECT school, student, student_number, grade_level, test_name,
  act_reading, act_math, act_english, act_science, act_composite,
  to_char(test_date, 'YYYY-MM-DD') AS test_date
FROM (
  SELECT schools.name AS school,
    s.lastfirst AS student,
    s.student_number,
    s.grade_level,
    t.name AS test_name,
    ts.name AS test_score_name,
    sts.numscore,
    st.test_date
  FROM students s
  JOIN studenttestscore sts ON s.id = sts.studentid
  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 schools ON s.schoolid = schools.school_number
  WHERE t.name = 'ACT'
  AND sts.numscore > 0 
  AND s.enroll_status=0
  AND s.schoolid=10
)
PIVOT (
  max(numscore)
  FOR test_score_name IN (
    'ACT_Reading' AS act_reading,
    'ACT_Math' AS act_math,
    'ACT_English' AS act_english,
    'ACT_Science' AS act_science,
    'ACT_Composite' AS act_composite
  )
) p
ORDER BY p.student, p.test_date DESC
在有效地旋转分数时,您不希望将其作为自己的列包含在“选择”列表或“分组依据”中

最好使用现代连接语法,而不是from子句中古老的逗号分隔表列表;您还应该在to_char调用中提供日期的格式模型:

SELECT schools.name AS school,
  s.lastfirst AS student,
  s.student_number,
  s.grade_level,
  t.name AS test_name,
  MAX(CASE WHEN ts.NAME = 'ACT_Reading' THEN sts.numscore END) AS act_reading,
  MAX(CASE WHEN ts.NAME = 'ACT_Math' THEN sts.numscore END) AS act_math,
  MAX(CASE WHEN ts.NAME = 'ACT_English' THEN sts.numscore END) AS act_english,
  MAX(CASE WHEN ts.NAME = 'ACT_Science' THEN sts.numscore END) AS act_science,
  MAX(CASE WHEN ts.NAME = 'ACT_Composite' THEN sts.numscore END) AS act_composite,
  to_char(st.test_date, 'YYYY-MM-DD') AS test_date
FROM students s
JOIN studenttestscore sts ON s.id = sts.studentid
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 schools ON s.schoolid = schools.school_number
WHERE t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
使用pivot的等效方法如下所示:

SELECT schools.name AS School,
  s.lastfirst AS Student,
  s.student_number,
  s.grade_level,
  t.name AS Test_Name,
  max(case when ts.name = 'ACT_Reading' then sts.numscore end) as ACT_Reading,
  max(case when ts.name = 'ACT_Math' then sts.numscore end) as ACT_Math,
  max(case when ts.name = 'ACT_English' then sts.numscore end) as ACT_English,
  max(case when ts.name = 'ACT_Science' then sts.numscore end) as ACT_Science,
  max(case when ts.name = 'ACT_Composite' then sts.numscore end) as ACT_Composite,
  to_char (st.test_date)
FROM students s,studenttestscore sts,studenttest st,test t,testscore ts,schools
WHERE s.id = sts.studentid
AND sts.studenttestid = st.id
AND sts.testscoreid = ts.id
AND ts.testid = t.id
AND s.schoolid = schools.school_number
AND t.name = 'ACT'
AND sts.numscore > 0 
and s.enroll_status=0
AND s.schoolid=10
GROUP BY schools.name,
  s.lastfirst,
  s.student_number,
  s.grade_level,
  t.name,
  st.test_date
ORDER BY s.lastfirst, st.test_date DESC
SELECT school, student, student_number, grade_level, test_name,
  act_reading, act_math, act_english, act_science, act_composite,
  to_char(test_date, 'YYYY-MM-DD') AS test_date
FROM (
  SELECT schools.name AS school,
    s.lastfirst AS student,
    s.student_number,
    s.grade_level,
    t.name AS test_name,
    ts.name AS test_score_name,
    sts.numscore,
    st.test_date
  FROM students s
  JOIN studenttestscore sts ON s.id = sts.studentid
  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 schools ON s.schoolid = schools.school_number
  WHERE t.name = 'ACT'
  AND sts.numscore > 0 
  AND s.enroll_status=0
  AND s.schoolid=10
)
PIVOT (
  max(numscore)
  FOR test_score_name IN (
    'ACT_Reading' AS act_reading,
    'ACT_Math' AS act_math,
    'ACT_English' AS act_english,
    'ACT_Science' AS act_science,
    'ACT_Composite' AS act_composite
  )
) p
ORDER BY p.student, p.test_date DESC
但无论如何,它都会转化为聚合/案例版本


当然,所有这些都未经测试,因为我们没有您的模式可供使用…

您走在正确的轨道上,您试图编写的是一个pivot查询。这是一个正确的版本。需要每个大小写表达式的最大值才能生成所需的单行值。此外,它在所有表之间使用适当的显式联接。这是编写现代SQL查询的首选方法

SELECT
    sc.name AS School,
    s.lastfirst AS Student,
    s.student_number,
    s.grade_level,
    t.name AS Test_Name,
    MAX(CASE WHEN ts.name = 'ACT_Reading'   THEN sts.numscore end) AS ACT_Reading,
    MAX(CASE WHEN ts.name = 'ACT_Math'      THEN sts.numscore end) AS ACT_Math,
    MAX(CASE WHEN ts.name = 'ACT_English'   THEN sts.numscore end) AS ACT_English,
    MAX(CASE WHEN ts.name = 'ACT_Science'   THEN sts.numscore end) AS ACT_Science,
    MAX(CASE WHEN ts.name = 'ACT_Composite' THEN sts.numscore end) AS ACT_Composite,
    TO_CHAR(st.test_date),
    sts.numscore AS Score
FROM students s
INNER JOIN studenttestscore sts
    ON s.id = sts.studentid
INNER JOIN studenttest st
    ON sts.studenttestid = st.id
INNER JOIN test score ts
    ON sts.testscoreid = ts.id
INNER JOIN test t
    ON ts.testid = t.id
INNER JOIN schools sc
    ON s.schoolid = sc.school_number
WHERE
    t.name = 'ACT' AND
    sts.numscore > 0 AND
    s.enroll_status = 0 AND
    s.schoolid = 10
GROUP BY
    sc.name,
    s.lastfirst,
    s.student_number,
    s.grade_level,
    t.name,
    st.test_date,
    sts.numscore
ORDER BY
    s.lastfirst,
    st.test_date DESC;

您所处的轨道是正确的,您试图编写的是一个pivot查询。这是一个正确的版本。需要每个大小写表达式的最大值才能生成所需的单行值。此外,它在所有表之间使用适当的显式联接。这是编写现代SQL查询的首选方法

SELECT
    sc.name AS School,
    s.lastfirst AS Student,
    s.student_number,
    s.grade_level,
    t.name AS Test_Name,
    MAX(CASE WHEN ts.name = 'ACT_Reading'   THEN sts.numscore end) AS ACT_Reading,
    MAX(CASE WHEN ts.name = 'ACT_Math'      THEN sts.numscore end) AS ACT_Math,
    MAX(CASE WHEN ts.name = 'ACT_English'   THEN sts.numscore end) AS ACT_English,
    MAX(CASE WHEN ts.name = 'ACT_Science'   THEN sts.numscore end) AS ACT_Science,
    MAX(CASE WHEN ts.name = 'ACT_Composite' THEN sts.numscore end) AS ACT_Composite,
    TO_CHAR(st.test_date),
    sts.numscore AS Score
FROM students s
INNER JOIN studenttestscore sts
    ON s.id = sts.studentid
INNER JOIN studenttest st
    ON sts.studenttestid = st.id
INNER JOIN test score ts
    ON sts.testscoreid = ts.id
INNER JOIN test t
    ON ts.testid = t.id
INNER JOIN schools sc
    ON s.schoolid = sc.school_number
WHERE
    t.name = 'ACT' AND
    sts.numscore > 0 AND
    s.enroll_status = 0 AND
    s.schoolid = 10
GROUP BY
    sc.name,
    s.lastfirst,
    s.student_number,
    s.grade_level,
    t.name,
    st.test_date,
    sts.numscore
ORDER BY
    s.lastfirst,
    st.test_date DESC;


谢谢你的回复!我运行了查询,但没有返回任何行。谢谢您的回复!我运行了查询,但没有返回任何行。谢谢您的回复。我每行只能得到一分。恐怕在看不到你的数据的情况下,这是我能给你的最大帮助。如果你想更进一步,那么在一个网站上设置一个演示,比如,也许我可以在那里看一看。非常感谢你的帮助!你是对的,我需要添加MAX和groupby子句。祝你有美好的一天!谢谢你的回复。我每行只能得到一分。恐怕在看不到你的数据的情况下,这是我能给你的最大帮助。如果你想更进一步,那么在一个网站上设置一个演示,比如,也许我可以在那里看一看。非常感谢你的帮助!你是对的,我需要添加MAX和groupby子句。祝你有美好的一天!谢谢你的回复。你的第一个查询成功了!!!非常感谢。我尝试了连接,但没有返回任何数据。@JBrown-如我所说,未经测试。。。但是您应该得到错误,而不是没有结果,您的客户机/应用程序是否以某种方式抑制了这些错误?我保持连接的顺序与您最初列出的表相同,但其中两个需要交换。我使用的是SQL Dev。如果您能提供帮助,我还有另一个问题,那将非常棒。我需要合计CASE语句中的5列,然后添加一个total列。我试过几种方法,但都不走运。非常感谢。如果使用前两个查询中的任何一个,则只需将SUMsts.numcore添加为total即可。如果有测试分数名称要排除,而不是您显示的五个,那么您可以添加一个筛选器或使该总和有条件。在真正的pivot版本中,您可以将列添加到一起——尽管如果有可以为null的列,您可能需要将它们合并为零。如果你真的陷入困境,那就问一个新问题。我添加了这个列,但在一些记录中,总数是错误的,但在其他记录中,总数是正确的?770 750零3040 720 790零1510谢谢你的回复。你的第一个查询成功了!!!非常感谢。我尝试了连接,但没有返回任何数据。@JBrown-如我所说,未经测试。。。但是您应该得到错误,而不是没有结果,您的客户机/应用程序是否以某种方式抑制了这些错误?我保持连接的顺序与您最初列出的表相同,但其中两个需要交换
我还有一个问题,如果你能帮忙,那就太棒了。我需要合计CASE语句中的5列,然后添加一个total列。我试过几种方法,但都不走运。非常感谢。如果使用前两个查询中的任何一个,则只需将SUMsts.numcore添加为total即可。如果有测试分数名称要排除,而不是您显示的五个,那么您可以添加一个筛选器或使该总和有条件。在真正的pivot版本中,您可以将列添加到一起——尽管如果有可以为null的列,您可能需要将它们合并为零。如果你真的陷入困境,那就问一个新问题。我添加了这个列,但在一些记录中,总数是错误的,但在其他记录中,总数是正确的?770 750零3040 720 790零1510