2015-02-06 6 views
1

Я работаю над этим запросом некоторое время и не могу понять эту проблему. Все, что я пытаюсь сделать, это получить информацию из таблицы (самый большой заказ, кто сделал этот заказ), сохранить его и распечатать результат в виде сообщения на консоли. Спасибо за твою помощь.Застрял с этой ошибкой SQL: «Должен объявить скалярную переменную @XYZ»

Вот мой запрос:

USE DB; 

DECLARE @BigCustomer table(CustomerName varchar(50), Itemtotal smallmoney); 

    INSERT @BigCustomer 
     SELECT (FirstName + ' ' + LastName), 
       MAX((ItemPrice - DiscountAmount) * Quantity) 
    FROM Orders as o join customers as c 
      on o.CustomerID = c.CustomerID 
     join OrderItems as oi 
       on o.OrderID = oi.OrderID 
    WHERE o.CustomerID = 3 
    GROUP BY (FirstName + ' ' + LastName), 
      ((ItemPrice - DiscountAmount) * Quantity) 

DECLARE @CN nvarchar(50); 
SET @CN = (SELECT CustomerName FROM @BigCustomer) 
DECLARE @IT smallmoney; 
SET @IT = (SELECT ItemTotal FROM @BigCustomer) 
DECLARE @PrintMessage nvarchar(50); 
SET @PrintMessage = N'The largest order of ' + 
    CONVERT(nvarchar(50), @IT) + N'was made by ' + @CN; 

GO 
PRINT @PrintMessage 
+0

Попробуйте использовать 'LIMIT' в свой' SET @CN = (SELECT CustomerName FROM @BigCustomer) 'например и другую команду' SET'. – Edper

+0

Можете ли вы предоставить образцы данных и желаемые результаты? Как написано, ваш оператор 'group by' не имеет большого смысла. Скорее всего, вам не нужны какие-либо из этих переменных ... – sgeddes

+0

'@ IT', вероятно, NULL. вы никогда не устанавливали его. Хотя вы устанавливаете '@ CN' дважды. 'SET @CN = (SELECT ItemTotal FROM @BigCustomer)' -> 'SET @IT = (SELECT ItemTotal FROM @BigCustomer)'? Может ли 'CONVERT (nvarchar (50), @IT) работать с нулями? – Brad

ответ

0

яппи! Я все выясняю. I DECLARE d две переменные и назначьте параметры отдельно вместо одной переменной.

Если я выполнить запрос я получаю сообщение:

Самый большой заказ $ 342,30 был сделан Дэйв Хантер.

Вот запрос:

Я думаю, что я, наконец, понял это.

DECLARE @LOrder table (OrdTot money, OrdID int);

ВСТАВИТЬ @LOrder

SELECT SUM ((OI.ItemPrice - OI.DiscountAmount) * OI.Quantity), OI.OrderID ОТ OrderItems AS О.И. GROUP BY OrderID

DECLARE @CName VARCHAR (100); DECLARE @OAmount money;

SET @CName = (SELECT TOP 1 C.FirstName + '' + C.LastName от клиентов C JOIN Заказы О на c.CustomerID = O.CustomerID РЕГИСТРИРУЙТЕСЬ @LOrder ло на lo.OrdID = O.OrderID ORDER BY lo.OrdTot DESC);

SET @OAmount = (SELECT TOP 1 OrdTot ОТ @LOrder ORDER BY OrdTot DESC);

PRINT 'Самый большой заказ $' + конвертировать (VARCHAR (50), @ OAmount) + 'была сделана' + @CName

+1

Как это можно использовать повторно, когда идентификатор клиента жестко запрограммирован и не имеет никакого соединения с запросом, вытягивая наибольшую сумму заказа? – ErikE

0

Судя по запросу вы публикуемую в качестве ответа, вы, кажется, запутался , Попробуйте создать результирующий скрипт, выполнив одно за раз. Прежде всего, не используйте переменные в начале, а возвращайте данные, используя обычный запрос.

И в качестве базового запроса используйте тот, который получает только самый большой заказ и его идентификатор. Для этого было бы достаточно, чтобы взять только OrderItems таблицу, сгруппировать данные по OrderID и ограничить результаты верхнего порядка общего:

SELECT TOP (1) 
    OrderID, 
    OrderTotal = SUM((ItemPrice - DiscountAmount) * Quantity) 
FROM 
    dbo.OrderItems 
GROUP BY 
    OrderID 
ORDER BY 
    OrderTotal DESC 
; 

Для того, чтобы узнать идентификатор клиента, который сделал заказ возвращается по вышеуказанному запросу вы можете добавить соединение к Orders. Вы также должны изменить предложения GROUP BY для включения CustomerID в него:

SELECT TOP (1) 
    o.CustomerID, 
    oi.OrderID, 
    OrderTotal = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity) 
FROM 
    dbo.OrderItems AS oi 
    INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID 
GROUP BY 
    oi.OrderID, 
    o.CustomerID 
ORDER BY 
    OrderTotal DESC 
;

На этом этапе вы можете хранить CustomerID в переменную временно и использовать его во втором запросе, чтобы прочитать имя клиента от Customers.Это на самом деле не нужно, так как вы можете вернуть все данные в одном запросе:

SELECT TOP (1) 
    CustomerName = c.FirstName + ' ' + c.LastName, 
    OrderTotal = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity) 
FROM 
    dbo.OrderItems AS oi 
    INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID 
    INNER JOIN dbo.Customers AS c ON o.CustomerID = c.CustomerID 
GROUP BY 
    oi.OrderID, 
    o.CustomerID, 
    c.FirstName, c.LastName 
ORDER BY 
    OrderTotal DESC 
;

Как вы можете видеть, другое присоединиться добавляются к запросу и предложения GROUP BY модифицируются еще раз, чтобы включить столбцы FirstName и LastName.

И теперь пришло время ввести назначение переменной для запроса, чтобы вместо возврата результатов в виде строки, которую вы могли бы сохранить и затем распечатать.

SELECT TOP (1) 
    @Customer  = c.FirstName + ' ' + c.LastName, 
    @LargestOrder = SUM((oi.ItemPrice - oi.DiscountAmount) * oi.Quantity) 
FROM 
    dbo.OrderItems AS oi 
    INNER JOIN dbo.Orders AS o ON oi.OrderID = o.OrderID 
    INNER JOIN dbo.Customers AS c ON o.CustomerID = c.CustomerID 
GROUP BY 
    oi.OrderID, 
    o.CustomerID, 
    c.FirstName, 
    c.LastName 
ORDER BY 
    OrderTotal DESC 
;

Обратите внимание, что запрос не использует фильтр WHERE. Вы не можете заранее знать идентификатор клиента. Это техника TOP (1) + ORDER BY, которая позволяет вам это выяснить.

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