4

schoolDB というデータベースと 2 つのデータベース テーブルがあります。

studenteducation

学生テーブルを作成します。

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

Education テーブルを作成します。

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 SchoolAND という名前の教育機関に通ったことがあり、別の学歴を持つコース名を持つすべての人を見つけられるようにしたいと考えていますlike biol。生物学に限らず、すべての科学を見つけたいので、複数の like ステートメントを入れる必要があります。

私はこれを試しました:

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 フィドル: http://sqlfiddle.com/#!3/666f8/2

4

6 に答える 6

3

これにより、institution テーブルをそれ自体と結合することにより、学生のリストと大学のコース数 (大学ごと) が得られます。

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

大学のコース名が必要な場合は、内部クエリでそれを返すことができます。ただし、大学のコースごとに 1 つのレコードしかないため、outerselectと は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%'
于 2013-09-23T02:08:21.967 に答える
2

簡単な答えです。

  1. 関心のあるすべての行を選択します (つまり、「Secondary School」またはコース名で)。
  2. 学生ごとの行数を数えます。
  3. 少なくとも 2 行ある学生を保持するようにフィルター処理します。
  4. ORDER BY中等学校が最初に表示されるようにするために、私は表現を使用します。

あなたの質問が不明なままになっているのは、行が 2 行を超える場合にどうなるかということです。この場合、それらはすべて表示されますが、クエリは簡単に調整できます (row_number を追加し、rn <= 2 でフィルター処理します)。

フィドル: 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

編集

コメントは、クエリが少なくとも 1 つの中学校と 1 つの他の教育があることを確認していないことを正しく指摘しています。中等学校が 2 つある場合もあれば、中学校がまったくない場合もあります。

これらのケースは、以下の少し複雑なクエリで処理できます。

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
于 2013-09-26T19:40:16.480 に答える
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%'
))

動作する必要がありますか?

于 2013-09-25T08:51:49.587 に答える
1

次の例では、2 つのクエリを結合する相関サブクエリで 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
             )
于 2013-09-26T10:31:34.033 に答える
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
    )

実際には、これらのクエリは両方とも、STUDENTNUMBER のすべての行を表示しますINSTITUTIONNAME = 'Secondary School'INSTITUTIONNAME <> 'Secondary School'

sql fiddle demo

于 2013-09-25T07:01:34.157 に答える