[英]Need help for SQL Server cursor
我有这张桌子:
我想要这个输出:
我正在使用此代码
DECLARE @InvoiceNo Varchar(100)
SET @InvoiceNo = '17-18/1003'
DECLARE @srNO Varchar(100)
PRINT @InvoiceNo
BEGIN
CREATE TABLE #tempTableNew
(
SrNO Varchar(100),
Description Varchar(100),
Qnty Varchar(100),
Unit Varchar(100),
Rate Varchar(100),
Amount Varchar(100)
)
DECLARE CREATFINALTABLE CURSOR FOR
SELECT
ROW_NUMBER() OVER(ORDER BY B.InvoiceNo ASC) AS 'SrNo'
FROM
Billing B
INNER JOIN
Furniture F on F.FurnitureID = B.ProductID
WHERE
B.InvoiceNo = @InvoiceNo
OPEN CREATFINALTABLE
FETCH NEXT FROM CREATFINALTABLE INTO @srNO
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT
CONVERT(varchar, @srNO) AS 'SrNo',
F.FurnitureName AS 'Description',
CONVERT(varchar, B.Quantity) AS 'Qnty',
CONVERT(varchar, U.UnitName) AS 'Unit',
CONVERT(varchar, B.Rate) AS 'Rate',
CONVERT(varchar, B.Amount) AS 'Amount'
INTO
#tempTable
FROM
Billing B
INNER JOIN
Furniture F on F.FurnitureID = B.ProductID
INNER JOIN
UnitMaster U ON U.UnitID = B.UnitID
WHERE
B.BillingID = @srNO
INSERT INTO #tempTableNew
SELECT *
FROM #tempTable
WHERE SrNo = @srNO
UNION ALL
SELECT
(@srNO) AS 'srNo',
('SIZE: ' + CONVERT(varchar, Length) + ' X' +
CONVERT(varchar, Breadth) + ' X' + CONVERT(varchar, Height)) AS '[Description]',
' ' AS 'Qnty', ' ' AS 'Unit', ' ' AS 'Rate', ' ' AS 'Amount'
FROM Billing
WHERE BillingID = @srNO
UNION ALL
SELECT
(@srNO) AS 'srNo',
'SPECS:' AS '[Description]',
' ' AS 'Qnty', ' ' AS 'Unit', ' ' AS 'Rate', ' ' AS 'Amount'
FROM #tempTable
WHERE SrNo = @srNO
FETCH NEXT FROM CREATFINALTABLE INTO @srNO
DROP TABLE #tempTable
END
SELECT *
INTO #formated
FROM #tempTableNew
SELECT * FROM #formated
DROP TABLE #tempTableNew
DROP Table #formated
CLOSE CREATFINALTABLE
DEALLOCATE CREATFINALTABLE
END
我得到了这个输出。 请帮助我获得所需的输出。 我想根据AreaOfUsage
显示基于组的AreaOfUsage
。 帮助我修改此光标,以便我可以获得所需的输出。 先感谢您..
样本数据
CREATE TABLE Product
([SrNo] int, [Description] varchar(100), [Size] varchar(100)
, [Specs] varchar(100), [Qnty] int, [Unit] varchar(5)
, [Rate] int, [Amount] int, [AreaOfUsage] varchar(100))
;
INSERT INTO Product
([SrNo], [Description],[Size], [Specs], [Qnty], [Unit], [Rate], [Amount], [AreaOfUsage])
VALUES
(1, 'Bed as per design and detail', 'test iu','7.00x4.00x2.00', 1, 'P.RFT', 35000, 35000, 'Bedroom'),
(2, 'Coffee Table as per design and detail', 'shdjh test','7.00x3.00x2.00', 1, 'P.RFT', 12500, 12500, 'Hall'),
(3, 'Day Bed as per design in white', 'day bed test','7.00x5.00x3.00', 1, 'P.RFT', 19630, 19630, 'Bedroom')
;
这种数据操作的范围不太适合 SQL,通常会在“表示层”中执行,但这里有一种方法,您可能会发现它很有帮助,它根本不需要使用游标。 它使用 CROSS APPLY 和 VALUES 而不是为每个输入行创建多行输出。 VALUES 区域的视觉布局易于控制。
修改后的答案
可在SQL Fiddle 中作为演示使用。
MS SQL Server 2014 架构设置:
CREATE TABLE Product
([SrNo] int, [Description] varchar(100), [Size] varchar(100)
, [Specs] varchar(100), [Qnty] int, [Unit] varchar(5)
, [Rate] int, [Amount] int, [AreaOfUsage] varchar(100))
;
INSERT INTO Product
([SrNo], [Description],[Size], [Specs], [Qnty], [Unit], [Rate], [Amount], [AreaOfUsage])
VALUES
(1, 'Bed as per design and detail', 'test iu','7.00x4.00x2.00', 1, 'P.RFT', 35000, 35000, 'Bedroom'),
(2, 'Coffee Table as per design and detail', 'shdjh test','7.00x3.00x2.00', 1, 'P.RFT', 12500, 12500, 'Hall'),
(3, 'Day Bed as per design in white', 'day bed test','7.00x5.00x3.00', 1, 'P.RFT', 19630, 19630, 'Bedroom')
;
查询 1 :
SELECT
CASE WHEN rn = 2 THEN concat(t.srNo, '') ELSE '' END srNo
, t.Description
, CASE WHEN rn = 2 THEN concat(t.Qnty, '') ELSE '' END Qnty
, CASE WHEN rn = 2 THEN concat(t.Unit, '') ELSE '' END Unit
, CASE WHEN rn = 2 THEN concat(t.Rate, '') ELSE '' END Rate
, CASE WHEN rn = 2 THEN concat(t.Amount, '') ELSE '' END Amount
FROM (
SELECT
p.*
, row_number() over(partition by AreaOfUsage
order by srNo, rn) as grporder
FROM (
SELECT
AreaOfUsage
, srNo
, ca.rn
, ca.Description
, Qnty
, Unit
, Rate
, Amount
FROM Product
CROSS APPLY (
VALUES
(1, AreaOfUsage),
(2, Description),
(3, Specs),
(4, Size)
) ca (rn, description)
) p
) t
WHERE (
(grporder = 1 )
OR (grporder > 1 and AreaOfUsage <> Description)
)
ORDER BY AreaOfUsage, grporder
结果:
| srNo | Description | Qnty | Unit | Rate | Amount |
|------|---------------------------------------|------|-------|-------|--------|
| | Bedroom | | | | |
| 1 | Bed as per design and detail | 1 | P.RFT | 35000 | 35000 |
| | 7.00x4.00x2.00 | | | | |
| | test iu | | | | |
| 3 | Day Bed as per design in white | 1 | P.RFT | 19630 | 19630 |
| | 7.00x5.00x3.00 | | | | |
| | day bed test | | | | |
| | Hall | | | | |
| 2 | Coffee Table as per design and detail | 1 | P.RFT | 12500 | 12500 |
| | 7.00x3.00x2.00 | | | | |
| | shdjh test | | | | |
查询 2 :
显示详细信息行以帮助理解
SELECT
p.*
, row_number() over(partition by AreaOfUsage
order by srNo, rn) as grporder
FROM (
SELECT
AreaOfUsage
, srNo
, ca.rn
, ca.Description
, Qnty
, Unit
, Rate
, Amount
FROM Product
CROSS APPLY (
VALUES
(1, AreaOfUsage),
(2, Description),
(3, Specs),
(4, Size)
) ca (rn, description)
) p
结果:
| AreaOfUsage | srNo | rn | Description | Qnty | Unit | Rate | Amount | grporder |
|-------------|------|----|---------------------------------------|------|-------|-------|--------|----------|
| Bedroom | 1 | 1 | Bedroom | 1 | P.RFT | 35000 | 35000 | 1 |
| Bedroom | 1 | 2 | Bed as per design and detail | 1 | P.RFT | 35000 | 35000 | 2 |
| Bedroom | 1 | 3 | 7.00x4.00x2.00 | 1 | P.RFT | 35000 | 35000 | 3 |
| Bedroom | 1 | 4 | test iu | 1 | P.RFT | 35000 | 35000 | 4 |
| Bedroom | 3 | 1 | Bedroom | 1 | P.RFT | 19630 | 19630 | 5 |
| Bedroom | 3 | 2 | Day Bed as per design in white | 1 | P.RFT | 19630 | 19630 | 6 |
| Bedroom | 3 | 3 | 7.00x5.00x3.00 | 1 | P.RFT | 19630 | 19630 | 7 |
| Bedroom | 3 | 4 | day bed test | 1 | P.RFT | 19630 | 19630 | 8 |
| Hall | 2 | 1 | Hall | 1 | P.RFT | 12500 | 12500 | 1 |
| Hall | 2 | 2 | Coffee Table as per design and detail | 1 | P.RFT | 12500 | 12500 | 2 |
| Hall | 2 | 3 | 7.00x3.00x2.00 | 1 | P.RFT | 12500 | 12500 | 3 |
| Hall | 2 | 4 | shdjh test | 1 | P.RFT | 12500 | 12500 | 4 |
原始回复
请注意,由于您没有提供示例数据,我的列并非都是 varchar,因此我求助于使用 CONCAT(...,'') 将每个非 varchar 列转换为 varchar。 参考这里的演示: SQL Fiddle
设置:
CREATE TABLE Ihavethistable
([SrNo] int, [Description] varchar(17), [Specs] varchar(12), [Qnty] int, [Unit] varchar(5), [Rate] int, [Amount] int, [AreaOfUsage] varchar(7))
;
INSERT INTO Ihavethistable
([SrNo], [Description], [Specs], [Qnty], [Unit], [Rate], [Amount], [AreaOfUsage])
VALUES
(1, 'bed as per...', 'test iu', 1, 'P.RFT', 35000, 35000, 'Bedroom'),
(2, 'coffee table...', 'shdjh test', 1, 'P.RFT', 12500, 12500, 'Hall'),
(3, 'day bed as per...', 'day bed test', 1, 'P.RFT', 19630, 19630, 'Bedroom')
;
查询:
select
case when ca.rn = 2 then concat(t.srNo,'') else '' end srNo
, ca.description
, case when ca.rn = 2 then concat(t.Qnty,'') else '' end Qnty
, case when ca.rn = 2 then concat(t.Unit,'') else '' end Unit
, case when ca.rn = 2 then concat(t.Rate,'') else '' end Rate
, case when ca.rn = 2 then concat(t.Amount,'') else '' end Amount
from Ihavethistable t
CROSS APPLY (
VALUES
(1, AreaOfUsage),
(2, Description),
(3, Specs)
) ca (rn, description)
order by t.srNo, ca.rn
结果:
| srNo | description | Qnty | Unit | Rate | Amount |
|------|-------------------|------|-------|-------|--------|
| | Bedroom | | | | |
| 1 | bed as per... | 1 | P.RFT | 35000 | 35000 |
| | test iu | | | | |
| | Hall | | | | |
| 2 | coffee table... | 1 | P.RFT | 12500 | 12500 |
| | shdjh test | | | | |
| | Bedroom | | | | |
| 3 | day bed as per... | 1 | P.RFT | 19630 | 19630 |
| | day bed test | | | | |
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.