Help with the query!

  • I came across a situation as follow

    CREATE TABLE DAYOFWEEK(WeekID INT IDENTITY,DAY NVARCHAR(50))

    CREATE TABLE SubjectToStudy(WeekID INT,SUBJECT NVARCHAR(50))

    INSERT INTO DAYOFWEEK VALUES('MONDAY')

    INSERT INTO DAYOFWEEK VALUES('TUESDAY')

    INSERT INTO DAYOFWEEK VALUES('WEDNESDAY')

    INSERT INTO SubjectToStudy VALUES(1,'PHYSICS')

    INSERT INTO SubjectToStudy VALUES(1,'CHEMISTRY')

    INSERT INTO SubjectToStudy VALUES(1,'MATHEMATICS')

    INSERT INTO SubjectToStudy VALUES(2,'COMPUTERSCIENCE')

    INSERT INTO SubjectToStudy VALUES(2,'BIOLOGY')

    INSERT INTO SubjectToStudy VALUES(3,'BOTANY')

    INSERT INTO SubjectToStudy VALUES(3,'PHYSICS')

    I want the output as

    MONDAYPHYSICSCHEMISTRYMATHEMATICS

    TUESDAYCOMPUTERSCIENCEBIOLOGY

    WEDNESDAYBOTANYPHYSICS

    I tried using Pivot table, but was not able come up with the above output. Could you guys please help!!!

  • What should your output recordset look like?

    Two columns for DAYOFWEEK and SUBJECTS

    Or multiple columns like: DAYOFWEEK, SUBJECT1, SUBJECT2, SUBJECT3, ...

    If the second is right, is there known maximum number of subjects per any day?

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Here's one possibility.

    Select

    dw.day + ' ' +

    (

    Select sts.Subject + ' '

    From SubjectToStudy sts

    Where dw.WeekID = sts.WeekID

    Order by WeekID

    For XML Path ('')

    ) as list

    From

    DAYOFWEEK dw

    ;

  • I worked on this for awhile and this was the best I could come up with...

    -- SAMPLE DATA

    IF OBJECT_ID('tempdb..#Weekday') IS NOT NULL DROP TABLE #Weekday; CREATE TABLE #Weekday(Weekday_id int identity primary key, [day] nvarchar(50));

    IF OBJECT_ID('tempdb..#SubjectToStudy') IS NOT NULL DROP TABLE #SubjectToStudy; CREATE TABLE #SubjectToStudy(Weekday_id int,[Subject] nvarchar(50));

    IF OBJECT_ID('tempdb..#output') IS NOT NULL DROP TABLE #output; CREATE TABLE #output(Weekday_id int, [day] nvarchar(50), classes nvarchar(255));

    INSERT INTO #Weekday VALUES(N'MONDAY'),(N'TUESDAY'),(N'WEDNESDAY');

    INSERT INTO #SubjectToStudy VALUES(1,N'PHYSICS'),(1,N'CHEMISTRY'),(1,N'MATHEMATICS'),(2,N'COMPUTERSCIENCE'),(2,N'BIOLOGY'),(3,N'BOTANY'),(3,N'PHYSICS')

    INSERT INTO #output

    SELECT w.Weekday_id, [day], s.[Subject]

    FROM #Weekday w

    JOIN #SubjectToStudy s ON w.Weekday_id=s.Weekday_id

    ORDER BY Weekday_id

    --THE ROUTINE:

    DECLARE @classlist nvarchar(300)='';

    UPDATE #output

    SET @classlist=classes=(CASE WHEN @classlist='' THEN [day]+' ' ELSE @classlist+' ' END)+classes

    FROM #output

    WHERE Weekday_id=1

    SET @classlist='';

    UPDATE #output

    SET @classlist=classes=(CASE WHEN @classlist='' THEN [day]+' ' ELSE @classlist+' ' END)+classes

    FROM #output

    WHERE Weekday_id=2

    SET @classlist='';

    UPDATE #output

    SET @classlist=classes=(CASE WHEN @classlist='' THEN [day]+' ' ELSE @classlist+' ' END)+classes

    FROM #output

    WHERE Weekday_id=3;

    ;WITH answer AS

    (SELECT m=DENSE_RANK() OVER (PARTITION BY Weekday_id ORDER BY LEN(classes) DESC),

    classes

    FROM #output)

    SELECT classes FROM answer

    WHERE m=1;

    --CLEANUP

    DROP TABLE #Weekday;

    DROP TABLE #SubjectToStudy;

    DROP TABLE #output

    GO

    Nice work k125

    "I cant stress enough the importance of switching from a sequential files mindset to set-based thinking. After you make the switch, you can spend your time tuning and optimizing your queries instead of maintaining lengthy, poor-performing code."

    -- Itzik Ben-Gan 2001

  • Are you sure that OP wants one column with all subjects concatenated?

    If not, then he might want dynamic cross-tab:

    SELECT dow.[DAY], s.[Subject], ROW_NUMBER() OVER (PARTITION BY dow.[DAY] ORDER BY s.[Subject]) SN

    INTO #ds

    FROM [DAYOFWEEK] AS dow

    JOIN SubjectToStudy AS s

    ON s.WeekId = dow.WeekId

    DECLARE @sql NVARCHAR(2000) = '';

    SELECT @sql = @sql + '

    ,MAX(CASE WHEN SN = ' + CAST(SN AS VARCHAR) + ' THEN [Subject] ELSE '''' END) AS Subject_' + CAST(SN AS VARCHAR)

    FROM (SELECT DISTINCT SN FROM #ds) q ORDER BY SN

    SET @SQL = 'SELECT [Day] ' + @SQL + ' FROM #ds GROUP BY [Day] ORDER BY [Day] '

    EXEC (@sql)

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (3/19/2013)


    Are you sure that OP wants one column with all subjects concatenated?

    Agreed. 🙂 My query just presents the results in the format the OP listed at the end of the post. But your question to the OP hasn't yet been answered so it's not clear if that's what is really needed.

  • kl25 (3/19/2013)


    Eugene Elutin (3/19/2013)


    Are you sure that OP wants one column with all subjects concatenated?

    Agreed. 🙂 My query just presents the results in the format the OP listed at the end of the post. But your question to the OP hasn't yet been answered so it's not clear if that's what is really needed.

    If you click "Quote" button on OP original post, you will find that is "output" list is tabular.

    So, looks like more cross-tab...

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Eugene Elutin (3/19/2013)


    kl25 (3/19/2013)


    Eugene Elutin (3/19/2013)


    Are you sure that OP wants one column with all subjects concatenated?

    Agreed. 🙂 My query just presents the results in the format the OP listed at the end of the post. But your question to the OP hasn't yet been answered so it's not clear if that's what is really needed.

    If you click "Quote" button on OP original post, you will find that is "output" list is tabular.

    So, looks like more cross-tab...

    Ohh.. :ermm: Thanks. Just learned something about how the forum posts work... I was going off of the display and didn't look at the formatting underneath. Given that, my query probably isn't helpful for this result. Appreciate the info about clicking "Quote".

  • I must admit the guy who wrote the query qith the XML logic was an eye opener for me, I reallyed liked that method best. The way I have been doing it can be veiwed below. njoy

    SELECT DAY,+ [1]+ ' ' +[2]+' '+[3]

    FROM(

    SELECT

    DAY,

    MAX(CASE

    WHEN ROWID = 1 THEN SUBJECT ELSE ''

    END) [1],

    MAX(CASE

    WHEN ROWID = 2 THEN SUBJECT ELSE ''

    END)[2],

    MAX(CASE

    WHEN ROWID = 3 THEN SUBJECT ELSE ''

    END)[3]

    FROM(

    SELECT ROWID= ROW_NUMBER()OVER(PARTITION BY DAY,DW.WEEKID ORDER BY dw.WEEKID), DW.DAY,SS.SUBJECT

    FROM #DAYOFWEEK DW

    JOIN #SubjectToStudy SS ON SS.WeekID = DW.WeekID

    )OQ

    GROUP BY DAY

    )II

  • raym85 (3/19/2013)


    I must admit the guy who wrote the query qith the XML logic was an eye opener for me, I reallyed liked that method best. The way I have been doing it can be veiwed below. njoy

    The query using XML is a well known string concatenation method (since SQL2005). It's kind of string aggregate, which concatenates strong values from multiple rows into single column/row.

    Your method was a classical fixed columns cross-tab (until you concatenated [1],[2] and [3] columns). It can also be achieved using PIVOT. Dynamic SQL allows to build dynamic cross-tab with unknown number of columns.

    All methods are absolute fine and can be used where relevant.

    _____________________________________________
    "The only true wisdom is in knowing you know nothing"
    "O skol'ko nam otkrytiy chudnyh prevnosit microsofta duh!":-D
    (So many miracle inventions provided by MS to us...)

    How to post your question to get the best and quick help[/url]

  • Thanks Fellas for such brilliant answers. A lot of things to learn from all the answers ... 🙂

  • Eugene Elutin (3/19/2013)


    Are you sure that OP wants one column with all subjects concatenated?

    If not, then he might want dynamic cross-tab:

    SELECT dow.[DAY], s.[Subject], ROW_NUMBER() OVER (PARTITION BY dow.[DAY] ORDER BY s.[Subject]) SN

    INTO #ds

    FROM [DAYOFWEEK] AS dow

    JOIN SubjectToStudy AS s

    ON s.WeekId = dow.WeekId

    DECLARE @sql NVARCHAR(2000) = '';

    SELECT @sql = @sql + '

    ,MAX(CASE WHEN SN = ' + CAST(SN AS VARCHAR) + ' THEN [Subject] ELSE '''' END) AS Subject_' + CAST(SN AS VARCHAR)

    FROM (SELECT DISTINCT SN FROM #ds) q ORDER BY SN

    SET @SQL = 'SELECT [Day] ' + @SQL + ' FROM #ds GROUP BY [Day] ORDER BY [Day] '

    EXEC (@sql)

    Brilliant stuff.. well done:cool:

Viewing 12 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic. Login to reply