2014-10-16 7 views
0

Мне нужна помощь в суммировании двух (или более) столбцов псевдонимов. Я знаю, что для этого мне нужна производная таблица, но до сих пор я теряюсь в онлайн-учебниках и документации, поскольку их примеры слишком просты. они имеют только одну таблицу, две колонки и т.д.Создание производной таблицы в SQL Server

Что может быть мой лучший вариант здесь: Мне нужно вычислить сумму двух столбцов псевдонима: «InFxO» и «OnTxO» и мой код выглядит следующим образом:

ALTER PROC [dbo].[DIFOTIS] 
@Mode as Varchar (5) 
AS 
Begin 
Declare 

@StartDate date, 
@EndDate date 

SET @StartDate= 
CASE @Mode 
WHEN 'MTD' THEN DATEADD(mm,DATEDIFF(mm,0,GETDATE()),0) 
WHEN 'YTD' THEN DATEADD(yy,DATEDIFF(yy,0,GETDATE()),0) 
WHEN 'QTD' THEN DATEADD(qq,DATEDIFF(qq,0,GETDATE()),0) 
WHEN 'WTD' THEN DATEADD(wk,DATEDIFF(wk,0,GETDATE()),0) 
END 
Set @EndDate= 
CASE @Mode 
WHEN 'MTD' THEN DATEADD(mm,DATEDIFF(mm,0,GETDATE())+1,0) 
WHEN 'YTD' THEN DATEADD(yy,DATEDIFF(yy,0,GETDATE())+1,0) 
WHEN 'QTD' THEN DATEADD(qq,DATEDIFF(qq,0,GETDATE())+1,0) 
WHEN 'WTD' THEN DATEADD(wk,DATEDIFF(wk,0,GETDATE())+1,0) 
END 


Select DATEPART(ISO_WEEK,d.DateOpn) AS 'Week#' 
,Clients.CustCateg, Clients.ClntGroup 
,d.DocumentCode as 'CORD_DocumentCode' 
,CDSPDocs.DocumentCode AS 'DESP_DocumentCode' 
,Count(CORDLines.Qnty) AS 'Cord_Lines' 
,SUM(CORDLines.Qnty) AS 'CORD_Qty' 
,Count(CDSPLines.Qnty) AS 'DESP_Lines' 
,Sum(CDSPLines.Qnty) AS 'DESP_Qty' 
,CDSPLines.Status, d.Status as d_status 
,d.OpenDate, d.DateDue 
,CDSPDocs.PostDate AS 'DESP_PostedDate' 
,d.DocType, DATEDIFF(day, d.OpenDate, d.DateDue) AS 'Lead times' 

    --in-full 

,CASE WHEN SUM(CORDLines.Qnty) = Sum(CDSPLines.Qnty) THEN '1' ELSE '0' END as InFxO 


    --On-Time by order according to Despatch SLAs 

,CASE WHEN (Clients.ClntGroup IN ('Local Market','Local Market - Pharm','Web Sales - Local','Web Sales - Export', 'Mail Order','Mail Order - Export')) AND (Datediff(day, d.OpenDate, CDSPDocs.PostDate) - (Datediff(Week, d.OpenDate, CDSPDocs.PostDate)*2) <= 2) then '1' 
     WHEN (Clients.ClntGroup = 'Export Market') AND (Datediff(day, d.OpenDate, CDSPDocs.PostDate) - (Datediff(Week, d.OpenDate, CDSPDocs.PostDate)*2) <= 14) then '1' 
     WHEN (Clients.ClntGroup = 'Export Market') or Clients.CustCateg = 'UK Transfer' AND (d.DateDue >= CDSPDocs.PostDate) then '1' 
     ELSE '0' 
     END as OnTxO 


From dbo.Documents AS d INNER JOIN 
    dbo.Clients ON d.ObjectID = dbo.Clients.ClntID AND Clients.ClientName <> 'Samples - Free/Give-aways' LEFT Outer JOIN 
    dbo.DocumentsLines AS CORDLines ON d.DocID = CORDLines.DocID AND CORDLines.TrnType = 'L' 
    LEFT OUTER JOIN 
    dbo.DocumentsLines AS CDSPLines ON CORDLines.TranID = CDSPLines.SourceID AND CDSPLines.TrnType = 'L' AND (CDSPLines.Status = 'Posted' OR CDSPLines.Status = 'Closed') LEFT OUTER JOIN 
    dbo.Documents AS CDSPDocs ON CDSPLines.DocID = CDSPDocs.DocID 

WHERE (d.DocType IN ('CASW', 'CORD','MORD')) 
AND (CORDLines.LneType NOT In ('Fght','MANF','Stor', 'PACK','EXPS')) 
AND d.DateOpn >= @StartDate AND d.DateOpn < @EndDate 
AND (CORDLines.LneType is not null) 
AND (d.DateDue <= Convert(Date, GetDate(), 101)) 

Group by d.DateOpn 
,d.DocumentCode 
,Clients.CustCateg 
,CDSPDocs.DocumentCode 
,d.[Status] 
,d.DocType 
,d.OpenDate 
,d.DateReq 
,CDSPDocs.PostDate 
,CDSPLines.[Status] 
,Clients.ClntGroup 
,d.DocumentName 
,d.DateDue 
,d.DateOpn 

ORDER BY d.DateOpn, 'Week#' 
    END 


GO 

Вся помощь приветствуется. H

+0

Вы упоминаете SUM столбцы InFxO и OnTxO, но эти выражения в настоящее время возвращают varchar, а не числовое значение. Является ли ваше намерение для выдачи CASE возвращать целочисленное значение 0 или 1? Вы просто хотите инкапсулировать весь запрос в производную таблицу и вернуть одну строку с SUM этих двух выражений? –

+0

Привет, Дэн, Спасибо за ваш ответ. Мое намерение состоит в том, чтобы возвращать целое число в столбце alias и иметь их SUM в третьем столбце (InFxO + OnTxO) ... затем использовать результат в вычисленном поле в SSRS «iif» 2, затем ... Извинения, но я не знаю, что вы имеете в виду, инкапсулируя весь запрос ... Я довольно новичок в этом мире SQL, и некоторые из «лучших практик» выходят за рамки моего объема. Я открыт для идей, если они улучшат мой запрос и научат меня, как это сделать в будущем. – Eric

ответ

0

Ниже приведен пример, который обертывает исходный запрос в производной таблице, так что вам не нужно повторять выражения CASE для СУММЫ. Вы могли бы аналогичным образом обернуть запрос в общем выражении таблицы для достижения того же результата.

Я предлагаю использовать одиночные кавычки только для того, чтобы заключать строковые литералы и включать идентификаторы (имена столбцов, псевдонимы и имена объектов) с квадратными скобками или двойными кавычками, как описано в справочной системе SQL Server Books Online (http://msdn.microsoft.com/en-us/library/ms175874.aspx). Идентификаторы должны быть заключены только в том случае, если они не соответствуют правилам именования идентификаторов или являются зарезервированным ключевым словом.

ALTER PROC dbo.DIFOTIS @Mode AS varchar(5) 
AS 
    BEGIN 
     DECLARE @StartDate date 
      , @EndDate date; 

     SET @StartDate = CASE @Mode 
          WHEN 'MTD' 
          THEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()), 0) 
          WHEN 'YTD' 
          THEN DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) 
          WHEN 'QTD' 
          THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()), 0) 
          WHEN 'WTD' 
          THEN DATEADD(wk, DATEDIFF(wk, 0, GETDATE()), 0) 
         END; 
     SET @EndDate = CASE @Mode 
         WHEN 'MTD' 
         THEN DATEADD(mm, DATEDIFF(mm, 0, GETDATE()) + 1, 0) 
         WHEN 'YTD' 
         THEN DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, 0) 
         WHEN 'QTD' 
         THEN DATEADD(qq, DATEDIFF(qq, 0, GETDATE()) + 1, 0) 
         WHEN 'WTD' 
         THEN DATEADD(wk, DATEDIFF(wk, 0, GETDATE()) + 1, 0) 
         END; 

     SELECT Week# 
       , CustCateg 
       , ClntGroup 
       , CORD_DocumentCode 
       , DESP_DocumentCode 
       , Cord_Lines 
       , CORD_Qty 
       , DESP_Lines 
       , DESP_Qty 
       , Status 
       , d_status 
       , OpenDate 
       , DateDue 
       , DESP_PostedDate 
       , DocType 
       , [Lead times] 
       , InFxO 
       , OnTxO 
       , InFxO + OnTxO AS InFullAndOneTime 
     FROM (

      SELECT DATEPART(ISO_WEEK, d.DateOpn) AS Week# 
        , Clients.CustCateg 
        , Clients.ClntGroup 
        , d.DocumentCode AS CORD_DocumentCode 
        , CDSPDocs.DocumentCode AS DESP_DocumentCode 
        , COUNT(CORDLines.Qnty) AS Cord_Lines 
        , SUM(CORDLines.Qnty) AS CORD_Qty 
        , COUNT(CDSPLines.Qnty) AS DESP_Lines 
        , SUM(CDSPLines.Qnty) AS DESP_Qty 
        , CDSPLines.Status 
        , d.Status AS d_status 
        , d.OpenDate 
        , d.DateDue 
        , CDSPDocs.PostDate AS DESP_PostedDate 
        , d.DocType 
        , DATEDIFF(DAY, d.OpenDate, d.DateDue) AS [Lead times] 

     --in-full 
        , CASE WHEN SUM(CORDLines.Qnty) = SUM(CDSPLines.Qnty) THEN 1 
         ELSE 0 
        END AS InFxO 
     --On-Time by order according to Despatch SLAs 
        , CASE WHEN (Clients.ClntGroup IN ('Local Market', 
                 'Local Market - Pharm', 
                 'Web Sales - Local', 
                 'Web Sales - Export', 
                 'Mail Order', 
                 'Mail Order - Export')) 
           AND (DATEDIFF(DAY, d.OpenDate, CDSPDocs.PostDate) 
            - (DATEDIFF(WEEK, d.OpenDate, 
               CDSPDocs.PostDate) * 2) <= 2) 
         THEN 1 
         WHEN (Clients.ClntGroup = 'Export Market') 
           AND (DATEDIFF(DAY, d.OpenDate, CDSPDocs.PostDate) 
            - (DATEDIFF(WEEK, d.OpenDate, 
               CDSPDocs.PostDate) * 2) <= 14) 
         THEN 1 
         WHEN (Clients.ClntGroup = 'Export Market') 
           OR Clients.CustCateg = 'UK Transfer' 
           AND (d.DateDue >= CDSPDocs.PostDate) THEN '1' 
         ELSE 0 
        END AS OnTxO 
      FROM dbo.Documents AS d 
        INNER JOIN dbo.Clients ON d.ObjectID = dbo.Clients.ClntID 
               AND Clients.ClientName <> 'Samples - Free/Give-aways' 
        LEFT OUTER JOIN dbo.DocumentsLines AS CORDLines ON d.DocID = CORDLines.DocID 
                    AND CORDLines.TrnType = 'L' 
        LEFT OUTER JOIN dbo.DocumentsLines AS CDSPLines ON CORDLines.TranID = CDSPLines.SourceID 
                    AND CDSPLines.TrnType = 'L' 
                    AND (CDSPLines.Status = 'Posted' 
                    OR CDSPLines.Status = 'Closed' 
                   ) 
        LEFT OUTER JOIN dbo.Documents AS CDSPDocs ON CDSPLines.DocID = CDSPDocs.DocID 
      WHERE (d.DocType IN ('CASW', 'CORD', 'MORD')) 
        AND (CORDLines.LneType NOT IN ('Fght', 'MANF', 'Stor', 
                'PACK', 'EXPS')) 
        AND d.DateOpn >= @StartDate 
        AND d.DateOpn < @EndDate 
        AND (CORDLines.LneType IS NOT NULL) 
        AND (d.DateDue <= CONVERT(date, GETDATE(), 101)) 
      GROUP BY d.DateOpn 
        , d.DocumentCode 
        , Clients.CustCateg 
        , CDSPDocs.DocumentCode 
        , d.Status 
        , d.DocType 
        , d.OpenDate 
        , d.DateReq 
        , CDSPDocs.PostDate 
        , CDSPLines.Status 
        , Clients.ClntGroup 
        , d.DocumentName 
        , d.DateDue 
        , d.DateOpn 
     ) AS derived_table 
     ORDER BY d.DateOpn 
       , Week#; 
    END; 
GO 
+0

Спасибо, он работает как шарм! – Eric

Смежные вопросы