【问题标题】:How to join Views with aggregate functions?如何使用聚合函数加入视图?
【发布时间】:2021-12-24 15:15:59
【问题描述】:

我的问题

#4 中,我无法连接两个视图,因为另一个视图具有聚合函数。与 #5

相同

问题

  1. 创建一个名为 studentDetails 的视图,该视图应显示学生姓名、入学日期、每单位总价以及就读科学或历史学科的学生的学科描述。

  2. 创建一个视图,将其命名为 BiggestPrice,它将显示主题 ID 和所有主题的最高单价总价。该视图应仅显示大于 1000 的最高单价总价。

--4.)   Create a view name it as studentDetails, that would should show the student name, 
--      enrollment date  the total price per unit and subject description of students who are 
--      enrolled on the subject Science or History.

CREATE VIEW StudentDetails AS 
SELECT StudName, EnrollmentDate



--5.)   Create a view, name it as BiggestPrice, that will show the subject id and highest total 
--      price per unit of all the subjects. The view should show only the highest total price per unit
--      that are greater than 1000.

CREATE VIEW BiggestPrice AS
SELECT SubjId, SUM(Max(Priceperunit)) FROM Student, Subject
GROUP BY Priceperunit

这是我的桌子:

CREATE TABLE Student(
    StudentId char(5) not null,
    StudName varchar2(50) not null,
    Age NUMBER(3,0),
    CONSTRAINT Student_StudentId PRIMARY KEY (StudentId)
);

CREATE table Enrollment(
    EnrollmentId    varchar2(10) not null, 
    EnrollmentDate  date not null,
    StudentId    char(5) not null,
    SubjId    Number(5) not null,
    constraint Enrollment_EnrollmentId primary key (EnrollmentId),
    constraint Enrollment_StudentId_FK foreign key (StudentId) references Student(StudentId),
    constraint Enrollment_SubjId_Fk foreign key (SubjId) references Subject(SubjId)
);

Create table Subject(
    SubjId number(5,0) not null,
    SubjDescription varchar2(200) not null,
    Units   number(3,0) not null,
    Priceperunit   number(9,0) not null,
    Constraint Subject_SubjId_PK primary key (SubjId)
);

【问题讨论】:

  • 每单位的总价格令人困惑。我认为应该是总价或单价
  • 问题 4 和 5 的英语不及格。给您一个单价,并要求您找到一个总单价,这将是单个单价。我希望提问者要求的是每个主题的总价格(这将是单位数乘以单位价格),但他们没有要求。
  • 这两个问题似乎都不需要聚合函数来解决。

标签: sql oracle ddl sql-view dml


【解决方案1】:

因为这似乎是一道作业题。

您需要使用JOINs。您当前的查询:

CREATE VIEW StudentDetails AS 
SELECT StudName, EnrollmentDate

没有FROM 子句,并且您对问题5 的查询使用旧的逗号连接语法,没有WHERE 过滤器;这与CROSS JOIN 相同,会将每个学生与每个学科联系起来,这不是您想要的。

不要使用旧的逗号连接语法,而是使用 ANSI 连接并明确声明连接条件。

SELECT <expression list>
FROM   student s
       INNER JOIN enrollment e ON ...
       INNER JOIN subject j ON ...

然后可以根据表之间的关系填写...(一般是一个表的主键=另一个表的外键)。

那么对于&lt;expression list&gt;,您需要在问题中包含要求的列:学生姓名和入学日期以及科目名称将是相应表格中的那些列;并且每单位总价格(我假设实际上是每个主题的总价格)将是一个计算。

然后是问题 4 的最后一部分。

谁就读于科学或历史学科。

添加WHERE 过滤器以仅包含这些主题的行。


对于问题 5,您不需要任何 JOINS,因为该问题仅询问 SUBJECT 表中的详细信息。

您需要添加一个WHERE 过滤器以显示“仅显示大于 1000 的最高单价总价”。这是一个简单的乘法,然后您可以通过比较是否为&gt; 1000 进行过滤。

然后你需要限制查询只返回“所有科目的单价最高”的行。从 Oracle 12 开始,这将使用 ORDER BY 子句按总价格的降序排列,然后使用 FETCH FIRST ROW ONLYFETCH FIRST ROW WITH TIES

【讨论】:

  • 很好的解释!
【解决方案2】:

不确定我是否完全理解,但我认为它是这样的:

注意事项:

  1. 始终使用 ID 过滤记录:
  • where su.SubjId in (1,2)

  1. 您可以在子查询中使用 max() 找到最大记录,并将其与主查询连接,如下所示:
  • where su2.SubjId = su.SubjId
    

  1. 您不能使用别名作为过滤器,因此您可以像这样过滤它:
  • ( su.Units * su.Priceperunit ) &gt; 1000

 CREATE VIEW StudentDetails AS 
select s.StudName,
       e.EnrollmentDate,
       su.SubjDescription,
       su.Units * su.Priceperunit TotalPrice
  from student s
 inner join Enrollment e
    on e.StudentId = s.StudentId
 inner join Subject su
    on su.SubjId = e.SubjId
    where su.SubjId   in (1,2)
    
 CREATE VIEW BiggestPrice AS  
 select su.SubjId, ( su.Units * su.Priceperunit ) TotalPrice 
 from Subject su
 where ( su.Units * su.Priceperunit ) = 
 (
select max(su2.Units * su2.Priceperunit)
from  Subject su2
where su2.SubjId = su.SubjId
 )
 and ( su.Units * su.Priceperunit ) > 1000

【讨论】:

  • “StudentDetails”视图是正确的,但“SubjDescription”列中包含“History”的行数很少。
  • 您可以添加过滤位置,例如 ==> where su.SubjId in (1,2)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-30
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-30
相关资源
最近更新 更多