簡體   English   中英

具有多個變量的 T-SQL SELECT

[英]T-SQL SELECT with multiple variables

我正在嘗試使用 SQL 語句和 NORTHWIND 數據庫獲取此輸出:

Employee Name:Nancy Davolio
Number of Sales:345
Total Sales:192107.60

Employee Name:Andrew Fuller
Number of Sales:241
Total Sales:166537.75

Employee Name:Janet Leverling
Number of Sales:321
Total Sales:202812.84

Employee Name:Margaret Peacock
Number of Sales:420
Total Sales:232890.85

Employee Name:Steven Buchanan
Number of Sales:117
Total Sales:68792.28

...還有 4 個條目

當我使用這個語句時:

USE Northwind

DECLARE @EmployeeName VARCHAR(40),
        @NumberOfSales INT,
        @TotalSales DECIMAL(10,2),
        @Counter TINYINT = 1,
        @NumEmployees INT = IDENT_CURRENT('dbo.Employees');

WHILE @Counter < @NumEmployees
BEGIN
    --SELECT @EmployeeName = E.FirstName+' '+E.LastName
    --SELECT @NumberOfSales = count(od.OrderID)
    SELECT @TotalSales = SUM(unitprice * quantity * (1 - Discount))
    FROM Employees E
    JOIN Orders AS O ON O.EmployeeID = E.EmployeeID
    JOIN [Order Details] AS OD ON OD.OrderID = O.OrderID
    WHERE E.EmployeeID = @Counter

    PRINT 'Employee Name:       '--+ @EmployeeName;
    PRINT 'Number of Sales:     '--+ LTRIM(STR(@NumberOfSales));
    PRINT 'Total Sales:         '+CONVERT(varchar(10),@TotalSales);
    PRINT '';

    SET @Counter += 1;
END

我可以讓每個選擇單獨工作,但我無法弄清楚讓單個SELECT語句完成所有工作的語法。 我也應該能夠用三個SET語句來做到這一點,但我也無法弄清楚。 指向這兩種可能性的指針會很棒。

這是實際的步驟措辭:“在循環中,使用 SELECT 語句檢索每個員工的名字和姓氏、每個員工處理的訂單數量以及每個員工的總銷售額(您正在處理每個員工一)。您需要將多個表連接在一起並使用聚合函數來獲得計數和總數。將串聯的全名、銷售額和總銷售額分配給適當的變量。”

輸出應該在消息選項卡中,除了上面列出的預期輸出之外,沒有其他表格或格式。

不需要循環(如果可能,應該避免RBAR - Row By Agonizing Row方法):

SELECT EmployeeID
       ,[Employee Name] = E.FirstName+' '+E.LastName
       ,[TotalSales] = SUM(unitprice * quantity * (1-Discount))
       ,[NumberOfSales] = COUNT(DISTINCT o.OrderID)
FROM Employees E
JOIN Orders AS O ON O.EmployeeID = E.EmployeeID
JOIN [Order Details] AS OD ON OD.OrderID = O.OrderID
GROUP BY E.EmployeeID, E.FirstName+' '+E.LastName
ORDER BY E.EmployeeID;

編輯:

循環版本 - 一次分配多個變量。

USE Northwind

DECLARE @EmployeeName VARCHAR(40),
        @NumberOfSales INT,
        @TotalSales DECIMAL(10,2),
        @Counter TINYINT = 1,
        @NumEmployees INT = IDENT_CURRENT('dbo.Employees');

WHILE @Counter < @NumEmployees
BEGIN
    SELECT @EmployeeName  = E.FirstName+' '+E.LastName
          ,@NumberOfSales = COUNT(DISTINCT o.OrderID)
          ,@TotalSales    = SUM(unitprice * quantity * (1 - Discount))
    FROM Employees E
    JOIN Orders AS O ON O.EmployeeID = E.EmployeeID
    JOIN [Order Details] AS OD ON OD.OrderID = O.OrderID
    WHERE E.EmployeeID = @Counter
    GROUP BY E.FirstName+' '+E.LastName;

    PRINT 'Employee Name:       '+ @EmployeeName;
    PRINT 'Number of Sales:     '+ LTRIM(STR(@NumberOfSales));
    PRINT 'Total Sales:         '+ CONVERT(varchar(10),@TotalSales);
    PRINT '';

    SET @Counter += 1;
END

請注意,當您有間隙時,使用WHILE循環可能非常低效(即,您從 1 開始到IDENT_CURRENT ,這可能是一種情況,您的 ID 為 1,5, 200671 並且最終會出現不必要的循環)。


編輯2:

似乎在選擇中發生多個分配時,似乎是必需的

我添加了GROUP BY因為 FirstName 和 LastName 沒有用聚合函數包裝。 您可以跳過該子句,但隨后您需要添加MIN/MAX函數:

SELECT @EmployeeName  = MIN(E.FirstName)+' '+MIN(E.LastName)
      ,@NumberOfSales = COUNT(DISTINCT o.OrderID)
      ,@TotalSales    = SUM(unitprice * quantity * (1 - Discount))
FROM Employees E
JOIN Orders AS O ON O.EmployeeID = E.EmployeeID
JOIN [Order Details] AS OD ON OD.OrderID = O.OrderID
WHERE E.EmployeeID = @Counter;
-- and we are sure that all values for First/Last nane are the same because of  
-- WHERE E.EmployeeID = @Counter

相關: Group by 子句

在標准 SQL 中,包含 GROUP BY 子句的查詢不能引用選擇列表中未在 GROUP BY 子句中命名的非聚合列

這應該做。 我使用 CROSS APPLY 取消旋轉該集合,然后相應地對其進行格式化。 您可以在名為“CROSS APPLY an Alternative Method to Unpivot”的文章中閱讀有關它的更多信息。 由於 SQL 與集合一起工作,因此在我看來,SQL 的輸入和輸出應該始終是一個集合。

我擔心您格式化的方式可能不是 SQL 的工作,但仍然可以使用“單個”選擇語句作為集合操作:

;WITH CTE AS 
(
SELECT 
        EMPLOYEENAME =    E.FirstName +' '+ E.LastName,  
        NUMBEROFORDERS =  COUNT(OD.OrderID),
        TOTALSALES =      SUM(unitprice * quantity * (1-Discount))

   FROM Employees E
   INNER JOIN Orders AS O ON O.EmployeeID = E.EmployeeID
   INNER JOIN [Order Details] AS OD ON OD.OrderID = O.OrderID
   GROUP BY E.FirstName + ' ' + E.LastName
)


SELECT COLNAME, ColValue
FROM CTE

CROSS APPLY ( VALUES ('Employe Name:', EMPLOYEENAME),
                     ('Number of Sales:', LTRIM(STR(NUMBEROFORDERS, 25, 5)) ),
                     ('Total Sales:', LTRIM(STR(TOTALSALES, 25, 5)) ),
                     ('','')

            ) A  (COLNAME, ColValue)

示例輸出如下:

COLNAME             ColValue
-------------   | ------------- 
Employe Name:   | Nancy Davolio
Number of Sales:|  345.00000
Total Sales:    |  192107.60432

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM