我有一个名为schoolDB的数据库和2个数据库表,
student
和education
创建学生表:
USE [schoolDB]
GO
/****** Object: Table [dbo].[tblStudent] Script Date: 09/22/2013 17:30:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tblStudent](
[STUDENTNUMBER] [varchar](50) NOT NULL,
[STUDENTNAME] [varchar](50) NULL,
[EDUCATIONID] [varchar](50) NULL,
CONSTRAINT [PK_tblStudent] PRIMARY KEY CLUSTERED
(
[STUDENTNUMBER] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
创建教育表:
USE [schoolDB]
GO
/****** Object: Table [dbo].[tblEducation] Script Date: 09/22/2013 17:31:30 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[tblEducation](
[EDUCATIONID] [varchar](50) NOT NULL,
[STUDENTNUMBER] [varchar](50) NULL,
[INSTITUTIONNAME] [varchar](50) NULL,
[COURSENAME] [varchar](50) NULL,
[GRADE] [varchar](50) NULL,
[YEAROFLEAVING] [varchar](50) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
以下是数据的屏幕截图:
我希望能够找到所有去过名为Secondary School
的机构名称并且拥有其他教育记录并且课程名称为like
biol
的人。不仅限于生物学,我想找到所有的科学,所以我需要发表多个相似的陈述。
我试过这个:
SELECT COUNT(*) AS 'Our Students',
DTOurStudents.STUDENTNAME
FROM (SELECT TOP 2 TBLSTUDENT.STUDENTNUMBER,
TBLSTUDENT.STUDENTNAME,
TBLEDUCATION.INSTITUTIONNAME,
TBLEDUCATION.COURSENAME
FROM TBLEDUCATION
INNER JOIN TBLSTUDENT
ON TBLEDUCATION.STUDENTNUMBER = TBLSTUDENT.STUDENTNUMBER
WHERE TBLEDUCATION.INSTITUTIONNAME LIKE '%Secondary School%')
DTOurStudents
GROUP BY DTOurStudents.STUDENTNAME
SQL FIDDLE: http://sqlfiddle.com/#!3/666f8/2
答案 0 :(得分:3)
这将为您提供一份学生名单和一系列大学课程(每所大学),并加入该机构表。
SELECT
STUDENTNUMBER,
SCHOOL_NAME,
COLLEGE_NAME,
count(*) as COLLEGE_COURSES
FROM (
SELECT
school.STUDENTNUMBER,
school.INSTITUTIONNAME AS SCHOOL_NAME,
college.INSTITUTIONNAME AS COLLEGE_NAME
FROM dbo.tblEducation as school
INNER JOIN dbo.tblEducation as college ON school.STUDENTNUMBER = college.STUDENTNUMBER
WHERE school.INSTITUTIONNAME = 'Secondary School'
AND college.INSTITUTIONNAME <> 'Secondary School'
AND (college.COURSENAME like 'biol%'
OR college.COURSENAME like 'math%'
OR college.COURSENAME like 'etc%')
) AS c
GROUP BY STUDENTNUMBER, SCHOOL_NAME, COLLEGE_NAME
如果你想要大学的coursename那么你可以在内部查询中返回它。但由于每个大学课程只有一个记录,外部select
和group by
将是多余的。
SELECT
school.STUDENTNUMBER,
school.INSTITUTIONNAME AS SCHOOL_NAME,
college.INSTITUTIONNAME AS COLLEGE_NAME,
college.COURSENAME
FROM dbo.tblEducation as school
INNER JOIN dbo.tblEducation as college ON school.STUDENTNUMBER = college.STUDENTNUMBER
WHERE school.INSTITUTIONNAME = 'Secondary School'
AND college.INSTITUTIONNAME <> 'Secondary School'
AND (college.COURSENAME like 'biol%'
OR college.COURSENAME like 'math%'
OR college.COURSENAME like 'etc%'
答案 1 :(得分:2)
一个简单的答案。
ORDER BY
中使用了一个表达式,以确保中学首先出现。你的问题不明确的是当行数超过2行时会发生什么。在这种情况下,它们都显示出来,但查询很容易调整(在rn&lt; = 2上添加row_number和filter)。
小提琴:http://sqlfiddle.com/#!3/666f8/89/0
WITH cte as (
SELECT
STUDENTNUMBER,
COURSENAME,
INSTITUTIONNAME,
COUNT(*) OVER (PARTITION BY STUDENTNUMBER) AS RecordCount
FROM tblEducation
WHERE INSTITUTIONNAME = 'Secondary School'
OR COURSENAME like 'biol%'
OR COURSENAME like 'math%'
OR COURSENAME like 'etc%'
)
select *
from cte
where RecordCount >= 2
order by
studentnumber,
case when institutionname = 'Secondary School' then 1 else 2 end
修改强>
评论正确指出查询不会检查是否至少有一所中学和另一所中学。可能有两所中学,或根本没有中学!
可以使用下面稍微复杂的查询处理这些案例:
WITH cte as (
SELECT
STUDENTNUMBER,
COURSENAME,
INSTITUTIONNAME,
SUM(CASE INSTITUTIONNAME WHEN 'Secondary School' THEN 1 END)
OVER (PARTITION BY STUDENTNUMBER) AS SecondarySchoolCount,
SUM(CASE WHEN INSTITUTIONNAME <> 'Secondary School'
AND COURSENAME LIKE 'biol%'
THEN 1 END)
OVER (PARTITION BY STUDENTNUMBER) AS CourseCount
FROM tblEducation
WHERE INSTITUTIONNAME = 'Secondary School'
OR COURSENAME like 'biol%'
OR COURSENAME like 'math%'
OR COURSENAME like 'etc%'
)
select *
from cte
where SecondarySchoolCount >= 1 AND CourseCount >= 1
order by
studentnumber,
case when institutionname = 'Secondary School' then 1 else 2 end
答案 2 :(得分:1)
如果要显示两个行,可以使用此查询:
select a.*
from tblEducation as a
where
exists (
select *
from tblEducation as t
where t.INSTITUTIONNAME = 'Secondary School' and t.STUDENTNUMBER = a.STUDENTNUMBER
) and
exists (
select *
from tblEducation as t
where t.INSTITUTIONNAME <> 'Secondary School' and t.STUDENTNUMBER = a.STUDENTNUMBER
)
或者你可以这样做:
with cte as (
select
a.STUDENTNUMBER
from tblEducation as a
group by
a.STUDENTNUMBER,
case when a.INSTITUTIONNAME = 'Secondary School' then 1 else 0 end
)
select a.*
from tblEducation as a
where
a.STUDENTNUMBER in (
select t.STUDENTNUMBER
from cte as t group by t.STUDENTNUMBER
having count(*) > 1
)
实际上,如果至少有一行INSTITUTIONNAME = 'Secondary School'
且至少有一行INSTITUTIONNAME <> 'Secondary School'
<强> sql fiddle demo 强>
答案 3 :(得分:1)
试试这个
WITH CTE AS
(
SELECT E.STUDENTNUMBER
FROM (SELECT * FROM TBLEDUCATION WHERE INSTITUTIONNAME LIKE '%Secondary School%') E
INNER JOIN (SELECT * FROM TBLEDUCATION WHERE INSTITUTIONNAME NOT LIKE '%Secondary School%' AND COURSENAME LIKE '%biol%') E1
ON E.STUDENTNUMBER=E1.STUDENTNUMBER
)
SELECT *
FROM TBLSTUDENT S
INNER JOIN TBLEDUCATION E
ON S.STUDENTNUMBER = E.STUDENTNUMBER
WHERE S.STUDENTNUMBER IN (SELECT STUDENTNUMBER FROM CTE)
答案 4 :(得分:1)
SELECT DISTINCT s.STUDENTNUMBER
FROM tblStudent s
INNER JOIN tblEducation e
ON (s.studentnumber = e.studentnumber and (
e.institutionname = 'Secondary School'
or e.coursename like '%biol%'
OR e.coursename like '%math%'
))
应该有用吗?
答案 5 :(得分:1)
以下示例在相关子查询上使用EXISTS运算符,该子查询具有连接两个查询
SELECT *
FROM dbo.tblEducation t
WHERE EXISTS (SELECT 1
FROM (SELECT e.STUDENTNUMBER
FROM dbo.tblEducation e
WHERE e.INSTITUTIONNAME = 'Secondary School'
) x JOIN (SELECT e2.STUDENTNUMBER
FROM dbo.tblEducation e2
WHERE e2.INSTITUTIONNAME != 'Secondary School'
) x2 ON x.STUDENTNUMBER = x2.STUDENTNUMBER
WHERE x.STUDENTNUMBER = t.STUDENTNUMBER
)
请参阅SQLFiddle
或者
SELECT *
FROM tblEducation t3
WHERE EXISTS(SELECT t.STUDENTNUMBER
FROM tblEducation t
WHERE t.INSTITUTIONNAME LIKE 'Secondary School'
AND EXISTS(SELECT 1
FROM tblEducation t2
WHERE t.STUDENTNUMBER = t2.STUDENTNUMBER
AND t2.INSTITUTIONNAME != t.INSTITUTIONNAME
)
AND t3.STUDENTNUMBER = t.STUDENTNUMBER
)