1

現在、SQLサーバーで作業しており、ストアドプロシージャを作成してデータを取得しています。私の要件は次のとおりです。

Table A:PersonId,FirstName,LastName,Address,CourseId
(Primary Key For Table B,Foreign Key Here)
Table B:CourseDescription,CourseId

現在、各コースには、そのコースに登録されている複数の学生がいる場合があります。私の要件は、各学生のLastNameFirstNameを連結することです。コースに 3 人以上の学生がいる場合、結果で別のフラグ値を「Y」に設定する必要があります。temp table を使用して Stored proc を使用し、段階的に更新しました。私のストアド プロシージャも次のようになります。一時テーブルには列があります。

SeqId,CourseId,CourseDescription,StudentNameConcat,IsMoreThan3

最初に、コース ID、説明を更新します。次に、このテーブルから、シーケンス id(SeqId) に基づいてループし、学生名のリストを列の値として取得し、宣言された変数に連結します。

このアプローチはセットベースのアプローチではないため、良くありません。内部クエリまたはループ結合を使用して、単一のクエリで代替アプローチが必要であると考えています。私はまだそれを読んで、単一のクエリで実装しようとしています。しかし、まだ手がかりが得られていません。

4

4 に答える 4

2

データ構造が正規化されていません。学生がこれまでに1つのコースしか受講できない場合を除きます。これは悪いことであり、修正する必要があります。

それとは別に、group concat関数をエミュレートしようとしています。これは 1 つのアプローチです。

SELECT courses.*, 
    LEFT(students , LEN(students)-1) AS students, 
    case when (select count(*) from @studentcourses where CourseId = courses.CourseId)>=3
      then 'y' else 'n' end
FROM courses
CROSS APPLY
(
    SELECT lastname + ' ' + firstname + ','
    FROM studentcourses
    WHERE courses.CourseId = studentcourses.CourseId
    FOR XML PATH('')
) t (students)
于 2013-08-24T18:00:59.190 に答える
2
select
    c.CourseId,
    c.CourseDescription,
    stuff(
        (
            select ', ' + s.FirstName + ' ' + s.LastName
            from Students as s
            where s.CourseId = c.CourseId
            for xml path(''), type
        ).value('.', 'nvarchar(max)')
    , 1, 2, '') as Students,
    case
        when (select count(*) from Students as s where s.CourseId = c.CourseId) >=3 then 'y'
        else 'n'
    end as flag
from Courses as c

簡単な説明。まず、文字列を xml に連結しますが、名前は空で要素データは', ' + s.FirstName + ' ' + s.LastName. その後、この xml をメソッドで nvarchar(max) として取得します(これにより、やvalueなどの名前にすべての特殊文字が保持されます)。その後、名前が連結されますが、その前にコンマがあるので、stuff関数を使用してそれをカットする必要があります。&>

sql fiddle demo

于 2013-08-24T19:22:15.013 に答える
1

コースに少なくとも 3 人がいる場合に各人のコースにフラグを立てたいだけの場合は、次のようにしてみてください。

SELECT T1.COURSEID, 
       T2.COURSEDESCRIPTION, 
       FIRSTNAME + ' ' + LASTNAME StudentNameConcat, 
       CASE 
         WHEN COUNT(*) 
                OVER ( 
                  PARTITION BY t1.COURSEID) >= 3 THEN 1 
         ELSE 0 
       END                        IsMoreThan3 
FROM   TABLEA T1 
       INNER JOIN TABLEB T2 
               ON T1.COURSEID = T2.COURSEID 

SQL Fiddleの実例を見ることができます。
これがどのように機能するかの説明が必要な場合は、コメントを残してください。

于 2013-08-24T18:03:10.733 に答える