-2

I have 3 tables that look something like this:

Table A
Student id   | Course Name |Course Section
1                 | English            |A
1                 | Math                |B
2                 | Chemistry        |C
2                 | History             |A

Table B
Course Name |Course Section |Instructor ID |Percentage
Math               |B                       |67890           |50
Math               |B                       |54321           |50
History            |A                       |67890           |100
English           |A                        |12345          |100
Chemistry       |C                       |09876           |100

Table C
Instructor ID       |Instructor Email
09876                 | instrchem@testco.us
12345                 |instreng@testco.edu
54321                 |instrmathalso@testco.us
67890                 |instrhist@testco.edu

I want the output of my query to look like this:

StudentID   Course Name   Section   Instructor Email
1                 English              A            instreng@testco.edu
1                 Math                  B            instrhist@testco.edu;instrmath@testco.us
2                 Chemistry          C            instrchem@testco.us
2                 History               A            instrhist@testco.us

I have tried creating a table variable, using coalesce, and a couple of other suggestions, but I'm not having any success. Any ideas would be greatly appreciated.

Thank you.
eileen

  • 1
    Is this for a homework assignment? If so, please post what you have so far and we can help you understand how to solve this. – Arthur D Apr 28 '16 at 15:12
  • You need something like MySQL's `GROUP_CONCAT`, which SQL Server doesn't have. You can emulate this somehow, though. See here: http://stackoverflow.com/questions/17591490/how-to-make-a-query-with-group-concat-in-sql-server – Thorsten Kettner Apr 28 '16 at 15:12
  • 1
    You can just `join` the 3 tables together. – Eric Apr 28 '16 at 15:14
  • Possible duplicate of [Simulating group\_concat MySQL function in SQL Server?](http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-sql-server) – Tab Alleman Apr 28 '16 at 15:26
  • @Eric yes, but that doesn't produce the concatenated instructor emails. – Tab Alleman Apr 28 '16 at 15:26

3 Answers3

0

You can try to join the three tables

SELECT      StudentID           = [TABLE A].[Student id]
            ,[TABLE A].[Course Name]
            ,Section            = [TABLE A].[Course Section]
            ,[TABLE C].[Instructor Email]
FROM        [TABLE A]
INNER JOIN  [TABLE B]
ON          [TABLE A].[Course Name]     = [TABLE B].[Course Name]
AND         [TABLE A].[Course Section]  = [TABLE B].[Course Section]
INNER JOIN  [TABLE C]
ON          [TABLE B].[Instructor ID]   = [TABLE C].[Instructor ID]
Tgo1014
  • 536
  • 1
  • 7
  • 17
0

Try this

    WITH    cte
          AS ( SELECT   A.Student_Id AS StudentID
                      , A.CourseName AS [Course Name]
                      , A.CourseSection AS Section
               FROM     #TableA A
                        INNER JOIN #TableB B
                        ON B.CourseName = A.CourseName
                           AND B.CourseSection = A.CourseSection
                        INNER JOIN #TableC C
                        ON B.InstructorID = C.InstuctorID
             )
    SELECT  cte.StudentID
          , cte.[Course Name]
          , cte.Section
          , STUFF((SELECT   ',' + InstructorEmail
                   FROM     #TableC c1
                            INNER JOIN #TableB b1
                            ON b1.InstructorID = c1.InstuctorID
                            INNER JOIN #TableA a1
                            ON a1.CourseName = b1.CourseName
                   WHERE    a1.Student_Id = cte.StudentID
                            AND b1.CourseName = cte.[Course Name]
                            AND a1.CourseSection = cte.Section
            FOR   XML PATH('')
                    , TYPE).value('(./text())[1]', 'varchar(max)'), 1, 1, '') AS [Instructor Email]
    FROM    cte
    GROUP BY cte.StudentID
          , cte.[Course Name]
          , cte.Section;
Drishya1
  • 254
  • 2
  • 4
0

You can do it using a scalar function and a cursor.

First create the tables with data:

CREATE TABLE dbo.Student
(
    StudentId int NOT NULL,
    CourseName nvarchar(20) NOT NULL,
    CourseSection nchar(1) NOT NULL
);

INSERT INTO dbo.Student (StudentId, CourseName, CourseSection)
    VALUES (1, N'English', N'A'),
        (1, N'Math', N'B'),
        (2, N'Chemistry', N'C'),
        (2, N'History', N'A');

CREATE TABLE dbo.Course
(
    CourseName nvarchar(20) NOT NULL,
    CourseSection nchar(1) NOT NULL,
    InstructorId int NOT NULL,
    [Percentage] int NOT NULL
);

INSERT INTO dbo.Course (CourseName, CourseSection, InstructorId, [Percentage])
    VALUES (N'Math', N'B', 67890, 50),
        (N'Math', N'B', 54321, 50),
        (N'History', N'A', 67890, 100),
        (N'English', N'A', 12345, 100),
        (N'Chemistry', N'C', 9876, 100);

CREATE TABLE dbo.Instructor
(
    InstructorId int NOT NULL,
    InstructorEmail nvarchar(50) NOT NULL
);

INSERT INTO dbo.Instructor (InstructorId, InstructorEmail)
    VALUES (09876, N'instrchem@testco.us'),
        (12345, N'instreng@testco.edu'),
        (54321, N'instrmathalso@testco.us'),
        (67890, N'instrhist@testco.edu');

Then create a scalar function which concatenates instructor emails. It uses a cursor to do this.

CREATE FUNCTION dbo.uf_ConcatEmails
(
    @CourseName nvarchar(20),
    @CourseSection nchar(1)
)
RETURNS nvarchar(500)
AS
BEGIN
    DECLARE @e nvarchar(500) = NULL;

    DECLARE myCursor CURSOR LOCAL
        FAST_FORWARD READ_ONLY
        FOR SELECT I.InstructorEmail
            FROM dbo.Course AS C
                INNER JOIN dbo.Instructor AS I
                    ON I.InstructorId = C.InstructorId
            WHERE C.CourseName = @CourseName AND C.CourseSection = @CourseSection
            ORDER BY I.InstructorEmail;

    OPEN myCursor;
    DECLARE @email nvarchar(50);
    FETCH NEXT FROM myCursor INTO @email;
    WHILE @@FETCH_STATUS = 0
    BEGIN
        SET @e = IIF(@e IS NULL, @email, CONCAT(@e, N';', @email));
        FETCH NEXT FROM myCursor INTO @email;
    END

    CLOSE myCursor;
    DEALLOCATE myCursor;

    RETURN @e;
END

Then do it!

SELECT StudentId, CourseName, CourseSection, dbo.uf_ConcatEmails(CourseName, CourseSection) AS 'InstructorEmail'
    FROM dbo.Student
    ORDER BY StudentId, CourseName;

enter image description here

RichardCL
  • 1,432
  • 10
  • 9
  • Thank you everyone for all your help! I finally solved it with some nested selects. It's not pretty, but it gets the job done! best, eileen – e centofanti May 02 '16 at 16:34
  • ,case when (select top(1) b1.percentage from tableb b1 where a.Course = b1.CourseName and a.section = b1.section order by b1.percentage asc) = 50 then (select c1.email_address from tablec c1 where c1.instructorId = (select top(1) b2.instructorId from tableb b2 where b2.CourseName= a.CourseName and b2.section = a.section b2.percentage = 50 order by b2.person_code_id asc) )+ '*' + (select c2.email_address from tablec c2 where c2.instructorId = (select top(1) b3.instructorId from tableb b3 where b3.CourseName= a.CourseName and b3.section = a.section b3.percentage = 50 – e centofanti May 02 '16 at 16:37
  • order by b3.person_code_id desc)) else (select c3.email_address from tablec c3 where c3.instructorId = (select b4.InstructorId from tableb b4 where b4.CourseName = a.CourseName and b4.section = a.section and b4.percentage = 100)) end as 'Instructor Email' – e centofanti May 02 '16 at 16:37