Search code examples
sql-servert-sqlglobal-temp-tables

Table order not being preserved when putting it into a global temp table


So I have this database mail query, and this is basically the exact same format I always use and it always works as expected. However, with this latest query, the order by portion is not being transferred to the global temp, so when I received the email, the order is all random. Here's the code:

SET QUOTED_IDENTIFIER ON

DECLARE @CODE NVARCHAR(MAX),
        @CODE_ROW_COUNT INT,
        @s VARCHAR(MAX)

SET @s = 'Assembly Weekly Pod Thruput - Week of ' + 
CONVERT(VARCHAR(12),DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0), 107)

IF OBJECT_ID('tempdb..##WeeklyPodThruput') IS NOT NULL
    BEGIN
        DROP TABLE ##WeeklyPodThruput
    END;

DECLARE @juangoal INT = 114500
DECLARE @leogoal INT = 68500
DECLARE @silvestregoal INT = 68500
DECLARE @jorgegoal INT = 68500
DECLARE @totalgoal INT = @juangoal+@leogoal+@silvestregoal+@jorgegoal
DECLARE @juanmingoal INT = 8600
DECLARE @leomingoal INT = 5150
DECLARE @silvestremingoal INT = 5150
DECLARE @jorgemingoal INT = 5150
DECLARE @totalmingoal INT = 
@juanmingoal+@leomingoal+@silvestremingoal+@jorgemingoal;


WITH CTE AS(

SELECT DISTINCT
    CASE 
        WHEN t.EmplCode IN ('68','180','100','309','105') THEN '(1) Juan Pod'
        WHEN t.EmplCode IN ('275','297','146') THEN '(2) Leo Pod'
        WHEN t.EmplCode IN ('148','206','259') THEN '(3) Silvestre Pod'
        WHEN t.EmplCode IN ('251','242','142') THEN '(4) Jorge Pod'
        ELSE 'N/A'
        END AS [Pod],
    t.JobNo,
    r.CycleTime*od.QtyOrdered AS [Units Completed],
    od.UnitPrice
FROM TimeTicketDet t 
    JOIN OrderRouting r ON r.JobNo = t.JobNo AND t.WorkCntr = '150' AND r.WorkCntr = 'Assembly'
    JOIN OrderDet od ON r.JobNo = od.JobNo
WHERE r.JobNo NOT IN
        (
        SELECT DISTINCT
            od.JobNo
        FROM OrderDet od 
            JOIN TimeTicketDet t ON od.JobNo = t.JobNo
        WHERE CAST(t.TicketDate AS DATE) < CAST(DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0) AS DATE) --CAST(GETDATE() AS DATE)
            AND t.PiecesFinished >= 1
            AND t.WorkCntr IN ('150')
        )
    AND CAST(t.TicketDate AS DATE) >= CAST(DATEADD(wk, DATEDIFF(wk,0,GETDATE()), 0) AS DATE)
    AND CAST(t.TicketDate AS DATE) < CAST(DATEADD(DAY, 8-DATEPART(dw, GETDATE()), CONVERT(DATE, GETDATE())) AS DATE) --= CAST(GETDATE() AS DATE)
    AND t.PiecesFinished >= 1
    AND od.QtyOrdered = 1
),

CTE2 AS(

SELECT
    CASE 
        WHEN (GROUPING(CTE.Pod) = 1) THEN 'Total'
        ELSE CTE.Pod
        END AS [Pod],
    SUM(CTE.UnitPrice) AS [$ Completed],
    SUM(CTE.[Units Completed]) AS [Minutes Completed],
    CASE CTE.Pod
        WHEN '(1) Juan Pod' THEN @juangoal
        WHEN '(2) Leo Pod' THEN @leogoal
        WHEN '(3) Silvestre Pod' THEN @silvestregoal
        WHEN '(4) Jorge Pod' THEN @jorgegoal
        END AS [$ Goal],
    FORMAT(SUM(CTE.UnitPrice)/
    CASE CTE.Pod
        WHEN '(1) Juan Pod' THEN @juangoal
        WHEN '(2) Leo Pod' THEN @leogoal
        WHEN '(3) Silvestre Pod' THEN @silvestregoal
        WHEN '(4) Jorge Pod' THEN @jorgegoal
        END, 'P') AS [$ Goal %],
    CASE CTE.Pod
        WHEN '(1) Juan Pod' THEN @juanmingoal
        WHEN '(2) Leo Pod' THEN @leomingoal
        WHEN '(3) Silvestre Pod' THEN @silvestremingoal
        WHEN '(4) Jorge Pod' THEN @jorgemingoal
        END AS [Minutes Goal],
    FORMAT(SUM(CTE.[Units Completed])/
    CASE CTE.Pod
        WHEN '(1) Juan Pod' THEN @juanmingoal
        WHEN '(2) Leo Pod' THEN @leomingoal
        WHEN '(3) Silvestre Pod' THEN @silvestremingoal
        WHEN '(4) Jorge Pod' THEN @jorgemingoal
        END, 'P') AS [Minutes Goal %]
FROM CTE
GROUP BY CTE.Pod WITH ROLLUP
HAVING SUM(CTE.UnitPrice) > 0

)

SELECT
    CTE2.Pod,
    '$ '+FORMAT(CTE2.[$ Completed], 'N0') AS [$ Completed],
    CASE
        WHEN CTE2.Pod = 'Total' THEN '$ '+FORMAT(@totalgoal, 'N0')
        ELSE '$ '+FORMAT(CTE2.[$ Goal], 'N0')
        END AS [$ Goal],
    CASE
        WHEN CTE2.Pod = 'Total' THEN FORMAT(CTE2.[$ Completed]/@totalgoal,'P')
        ELSE CTE2.[$ Goal %]
        END AS [$ Goal %],
    FORMAT(CTE2.[Minutes Completed], 'N0') AS [Minutes Completed],
    CASE
        WHEN CTE2.Pod = 'Total' THEN FORMAT(@totalmingoal, 'N0')
        ELSE FORMAT(CTE2.[Minutes Goal], 'N0')
        END AS [Minutes Goal],
    CASE
        WHEN CTE2.Pod = 'Total' THEN FORMAT(CTE2.[Minutes Completed]/@totalmingoal,'P')
        ELSE CTE2.[Minutes Goal %]
        END AS [Minutes Goal %]
INTO ##WeeklyPodThruput
FROM CTE2
GROUP BY CTE2.Pod, CTE2.[$ Completed], CTE2.[Minutes Completed], CTE2.[$ Goal], CTE2.[$ Goal %], CTE2.[Minutes Goal], CTE2.[Minutes Goal %]
ORDER BY (CASE
            WHEN CTE2.Pod LIKE '%Pod' THEN 2
            WHEN CTE2.Pod = 'N/A' THEN 1
            ELSE 0
            END) DESC, SUM(CTE2.[Minutes Completed])/
                       CASE CTE2.Pod
                           WHEN '(1) Juan Pod' THEN @juanmingoal
                           WHEN '(2) Leo Pod' THEN @leomingoal
                           WHEN '(3) Silvestre Pod' THEN @silvestremingoal
                           WHEN '(4) Jorge Pod' THEN @jorgemingoal
                           END DESC

SELECT @CODE_ROW_COUNT = @@ROWCOUNT

IF(@CODE_ROW_COUNT > 0)

BEGIN

SET @CODE =
N'SELECT
  *
  FROM ##WeeklyPodThruput'

DECLARE @html nvarchar(MAX);
EXEC spQueryToHtmlTable 
@html = @html OUTPUT,  
@query = @CODE

EXEC msdb.dbo.sp_send_dbmail
    @profile_name = '123abc',
    @recipients = '[email protected]',
    @subject = @s,
    @body = @html,
    @body_format = 'HTML',
    @query_no_truncate = 1,
    @attach_query_result_as_file = 0,
    @execute_query_database = '123';

END

IF OBJECT_ID('tempdb..##WeeklyPodThruput') IS NOT NULL
    BEGIN
        DROP TABLE ##WeeklyPodThruput
    END

Funny thing is, it had been working perfectly fine for the past couple weeks, but this week when I saw the email, it was all out of order and it was odd. If I run the query portion alone, it runs and displays as expected, however, if I put the query in a global temp and immediately query that, it's out of order. I have like 30 of these and the order by portion always transfers correctly, not sure what is going on now.


Solution

  • Your query:

    SET @CODE =
    N'SELECT
      *
      FROM ##WeeklyPodThruput'
    

    Have no "ORDER BY" clause and I assume "spQueryToHtmlTable" don't force any order, so by definition you can get results in any order. You need to add "ORDER BY" to this query.

    To do this you can add 2 columns to your temp table:

    CASE
       WHEN CTE2.Pod LIKE '%Pod' THEN 2
       WHEN CTE2.Pod = 'N/A' THEN 1
       ELSE 0
    END AS Order1,
    SUM(CTE2.[Minutes Completed])/
       CASE CTE2.Pod
       WHEN '(1) Juan Pod' THEN @juanmingoal
       WHEN '(2) Leo Pod' THEN @leomingoal
       WHEN '(3) Silvestre Pod' THEN @silvestremingoal
       WHEN '(4) Jorge Pod' THEN @jorgemingoal
    END AS Order2
    

    and then use Order1 and Order2 in select from temp table.