我有两张桌子:
Sales.SalesOrderHeader(SalesOrderID(PK), SalesOrderNumber, Status,..)
Sales.SalesOrderDetail(SalesOrderID(PK,FK), ..)
我已声明变量@numdetail
和游标SaleReportCursor
。
我该如何打印:
SalesOrderNumber1 (3 items) was shipped.
SalesOrderNumber2 (4 items) was shipped.
SalesOrderNumber3 (2 items) was shipped.
是否可以对具有相同SalesOrderID
的产品进行分组和计数?
这就是我为光标所做的:
DECLARE
@salesOrderID INT,
@salesOrderNum NVARCHAR(25),
@dueDate DATETIME,
@status tinyint,
@message varchar(80),
@numDetail INT,
@count INT = 0,
@astatus varchar(10);
DECLARE salesReportCursor CURSOR
FOR
select s.SalesOrderID, SalesOrderNumber,DueDate, Status
FROM [Sales].[SalesOrderDetail] s
join Sales.SalesOrderHeader h
on s.SalesOrderID=h.SalesOrderID
where
h.DueDate between '2008-08-01' and '2008-08-31'
group by SalesOrderNumber,s.SalesOrderID,DueDate, Status
Order by SalesOrderNumber desc
FOR READ ONLY
OPEN salesReportCursor
FETCH NEXT from salesReportCursor
INTO @salesOrderID, @salesOrderNum , @dueDate , @status;
WHILE @@FETCH_STATUS = 0
BEGIN
set @numDetail= 1
if @salesOrderNum =@salesOrderNum
set @numDetail=@numDetail+1
Set @astatus=
case when @status=1 then 'In process'
when @status=2 then 'Approved'
when @status=3 then 'Backordered'
when @status=4 then 'Rejected'
when @status=5 then 'Shipped'
when @status=6 then 'Cancelled'
end
Select @message=cast(@salesOrderNum as varchar)
+' ('+ cast(@numDetail as varchar)+' items) due '+
cast(@dueDate as varchar) +' is '+ @astatus
set @count=@count+1
Print @message
FETCH NEXT from salesReportCursor
INTO @salesOrderID, @salesOrderNum , @status;
END
CLOSE salesReportCursor
DEALLOCATE salesReportCursor
我的结果如下:
SalesOrderNumber1 (2 items) was shipped.
SalesOrderNumber2 (2 items) was shipped.
SalesOrderNumber3 (2 items) was shipped.
我认为这是因为在BEGIN之后,我将@numdetail
最初设置为每行1,然后将其添加1.我想知道如何对具有相同SalesOrderID
的产品进行分组和计数?< / p>
答案 0 :(得分:1)
你根本不需要光标...
请尝试此操作(使用COUNT获取每个订单的商品数量):
select
SalesOrderNumber + ' (' + CONVERT(varchar, COUNT(*)) + ' items) due ' + CONVERT(varchar, h.DueDate, 20) + ' is ' + Statuses.Name
FROM
[Sales].[SalesOrderDetail] s
join Sales.SalesOrderHeader h
on s.SalesOrderID=h.SalesOrderID
join (
select 1 as Status, 'In process' as Name
union all select 2, 'Approved'
union all select 3, 'Backordered'
union all select 4, 'Rejected'
union all select 5, 'Shipped'
union all select 6, 'Cancelled'
) Statuses on
Statuses.Status = h.Status
where
h.DueDate between '2008-08-01' and '2008-08-31'
group by
h.SalesOrderNumber,
s.SalesOrderID,
h.DueDate,
h.Status
Order by
h.SalesOrderNumber desc
(我自己没有尝试过代码,所以可能会出现一些语法错误,但我希望你能明白这一点)
您还应该将状态放在自己的表中...最好是没有标识列的表,并将其用作查找表。