0

我们可以在返回一行结果的 SELECT 中创建一个子查询吗?

例如,我必须使用如下查询:

SELECT columnA as aliasA, columnB as aliasB,
(SELECT columnC FROM table2
WHERE clause2) as aliasC,
(SELECT  columnD FROM table2
WHERE clause2) as  aliasD
FROM table1
WHERE clause1

我想改进它,因为它需要太多时间来执行。有什么方法可以创建查询,例如:

SELECT columnA as aliasA, columnB as aliasB,
(SELECT columnC, columnD FROM table2
WHERE clause2) as (aliasC, aliasD)
FROM table1
WHERE clause1

谢谢

注意:更具体地说,我举一个例子:我需要在第一季度的每个月获得学生的最佳和最差成绩。如果我加入表格,我将为同一个学生提供不止一行(每个月一个)但我需要:

SELECT firstname, lastname, 
(SELECT MAX(value) FROM results WHERE results.student_id = student.id AND results.date
BETWEEN 'JAN-01' AND 'JAN-31') AS best_result_of_jan,
(SELECT MIN(value) FROM results WHERE results.student_id = student.id AND results.date
BETWEEN 'JAN-01' AND 'JAN-31') AS worst_result_of_jan,
 ..., 
(SELECT MIN(value) FROM results WHERE results.student_id = student.id 
AND results.date BETWEEN 'MAR-01' AND 'MAR-31') AS worst_result_of_mar 
FROM student 
WHERE student.has_maths = 1
4

3 回答 3

3

编辑

SELECT s.firstname, s.lastname,
       t.best_result_of_jan, t.worst_result_of_mar
FROM student s 
LEFT JOIN (
    (SELECT student_id,
            MAX(CASE WHEN results.date BETWEEN 'JAN-01' AND 'JAN-31'
                     THEN value ELSE NULL END) best_result_of_jan,
            MIN(CASE WHEN results.date BETWEEN 'MAR-01' AND 'MAR-31'
                     THEN value ELSE NULL END) worst_result_of_mar
     FROM results
     GROUP BY student_id
    ) t ON t.student_id = s.id
WHERE s.has_maths = 1

子查询将数据透视到每个学生所需的列中。然后,外部查询将这些列添加到学生表列中。


首先,只有当子查询返回标量结果(即单行或无)时,您的原始查询才会起作用。这样可以安全地转换为 LEFT JOIN 表单,这也可能导致单行(无笛卡尔积)或无行(fizzed join)。

   SELECT a.columnA as aliasA, a.columnB as aliasB,
          b.columnC as aliasC, b.columnD as aliasD
     FROM table1 a
LEFT JOIN table2 b ON clause2
    WHERE clause1;

确保为第 1 和 2 条中的列设置别名。

注意:此类查询的计划将导致 table2 被处理一次,并且 columnC/D 被解析。您的原始查询可能会导致子查询逐行执行,并导致两次启动,因此缺乏性能。

于 2013-04-17T13:48:49.823 回答
2

您想要加入,例如:

SELECT table1.columnA as aliasA, table1.columnB as aliasB, 
       table2.columnC as aliasC,
       table2.columnD as aliasD
FROM table1 left outer join
     table2
     on clause2
WHERE clause1
于 2013-04-17T13:48:20.730 回答
0

在您的查询中,如果数据范围参数相同,那么您可以编写一个带有最小值和最大值字段的单个选择语句。在您当前的情况下,除了其他解决方案之外,您可以尝试使用 UNION ALL 语句并组合两组查询。这可能比子查询方法更快。例子:

Select A.FirstName,
   A.LastName,
   Sum(A.Best_JAN) as BEST_JAN,
   sum(A.Worst_MAR) as WORST_MAR
From (

    Select student.FirstName,
            student.LastName,
            MAX(result.value) as Best_JAN,
            0 as Worst_MAR
      From Student, Results
     Where Student.Studentid = Results.studentid
       and results.date BETWEEN 'JAN-01' AND 'JAN-31'
     Group By student.FirstName, student.LastName

    Union ALL

    Select student.FirstName,
           student.LastName,
           0 as Best_JAN,
           MIN(result.value) as Worst_MAR
      From Student, Results
     Where Student.Studentid = Results.studentid
       And results.date BETWEEN 'MAR-01' AND 'MAR-31'
     Group By student.FirstName, student.LastName

  ) as A

  Group By A.FirstName, A.LastName
于 2013-04-17T14:17:18.043 回答