简体   繁体   English

使用SQL显示基于记录计数的结果

[英]Displaying results based on record count using SQL

I have database called schoolDB and 2 database tables, 我有一个名为schoolDB的数据库和2个数据库表,

student and education studenteducation

Create student table: 创建学生表:

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

Create Education table: 创建教育表:

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

Here is a screenshot of the data: 以下是数据的屏幕截图:

在此输入图像描述

I want to be able to find every one who has been to an institution name called Secondary School AND who has another education record with a course name like biol . 我希望能够找到每个去过一所名为Secondary School的机构名称的人,并且他的另一个教育记录是like biol like的课程名称。 Not just limited to biology, i want to find all the sciences, so i need to put multiple like statements. 不仅限于生物学,我想找到所有的科学,所以我需要提出多个相似的陈述。

I have tried this: 我试过这个:

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 SQL FIDDLE: http ://sqlfiddle.com/#!3/666f8/2

This will give you a list of students and a count of college courses (per college), by joining the institution table with itself. 这将为您提供一份学生名单和大学课程(每所大学),通过加入机构表自己。

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

If you want the college coursename then you can return that in the inner query. 如果你想要大学的coursename那么你可以在内部查询中返回。 But since there is only one record per college course, the outer select and the group by would be redundant. 但由于每个大学课程只有一个记录,外部selectgroup 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%'

A simple answer. 一个简单的答案。

  1. I select all rows of interest (ie 'Secondary School' or by coursename). 我选择所有感兴趣的行(即'中学'或通过coursename)。
  2. I count the number of rows per student. 我计算每个学生的行数。
  3. I filter to keep the students that have at least 2 rows. 我过滤以保持至少有2行的学生。
  4. I use an expression in the ORDER BY to make sure secondary school shows up first. 我在ORDER BY使用表达式来确保中学首先出现。

What your question left unclear is what should happen when there are more than 2 rows. 您的问题不明确的是当有超过2行时会发生什么。 In this case they all show up, but the query is easy enough to adjust (add a row_number and filter on rn <= 2). 在这种情况下,它们都会显示,但查询很容易调整(在rn <= 2上添加row_number和filter)。

Fiddle: http://sqlfiddle.com/#!3/666f8/89/0 小提琴: 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

EDIT 编辑

A comment correctly points out that the query doesn't check that there is at least one secondary school and one other education. 评论正确地指出查询不会检查是否至少有一所中学和另一项教育。 There could be two secondary schools, or no secondary school at all! 可能有两所中学,或根本没有中学!

Those cases can be handled with the slightly more complicated query below: 可以使用下面稍微复杂的查询来处理这些情况:

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

If you want both rows to show up, you can use this query: 如果要显示两个行,可以使用此查询:

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  
    )

or you can do it like this: 或者你可以这样做:

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
    )

Actually both of these queries diplay all rows for STUDENTNUMBER if there exists at least one row with INSTITUTIONNAME = 'Secondary School' and at least one row with INSTITUTIONNAME <> 'Secondary School' 实际上,如果至少有一行包含INSTITUTIONNAME = 'Secondary School'且至少有一行包含INSTITUTIONNAME <> 'Secondary School' ,则这两个查询都会显示STUDENTNUMBER的所有行

sql fiddle demo sql小提琴演示

Try this 尝试这个

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)
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%'
))

Should work? 应该管用?

The following example uses the EXISTS operator on a correlated subquery, that has a joining two queries 以下示例在相关子查询上使用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
              )

See demo on SQLFiddle 请参阅SQLFiddle演示

Or 要么

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
             )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM