SQL - 根据条件对行进行分组并显示总计

时间:2013-02-26 20:20:01

标签: sql tsql sql-server-2008-r2

不太确定如何在这上面加上标题,但我尽我所能。我有一个报告显示所选位置的所有资产。我们的一个问题是我们将一切都追踪为资产。因此,典型的计算机系统将有5台计算机,8台显示器,但有10多条网络电缆。我正在尝试编写一份报告,“汇总”任何不必要的项目并显示计数而不是实际项目。

例如,我想这样:

Desc            | Manufacturer  | Serial Number
-----+-------    ----+--------------------
20" monitor     | Dell          | 123456
25" monitor     | Dell          | 123456ab
6ft Net. Cable  | N/A           | NA123
6ft Net. Cable  | N/A           | NA124
6ft Net. Cable  | N/A           | NA125
6ft Net. Cable  | N/A           | NA456
1TB SATA HD     | SeaGate       | SG125000
1.5TB SATA HD   | SeaGate       | SG100000

成为:

Desc            | Manufacturer  | Serial Number/Qnty
-----+-------    ----+-----------------------------
20" monitor     | Dell          | 123456
25" monitor     | Dell          | 123456ab
6ft Net. Cable  | N/A           | 4
1TB SATA HD     | SeaGate       | SG125000
1.5TB SATA HD   | SeaGate       | SG100000

这是我的SQL让我获得了最高分,但我不太确定哪里可以开始获得最低分。

SELECT i.ItemDescription AS Desc, s.Name AS Manufacturer, inv.SerialNumber AS [Serial Number]
FROM Assets a 
LEFT OUTER JOIN Inventory inv ON a.InventoryID = inv.InventoryID 
LEFT OUTER JOIN Items i ON inv.ItemID = i.ItemID 
LEFT OUTER JOIN Rooms r ON a.RoomID = r.RoomID 
LEFT OUTER JOIN Locations l ON r.LocationID = l.LocationID 
LEFT OUTER JOIN Suppliers s ON i.ManufacturerID = s.SupplierID 
WHERE l.LocationID = 5

我需要将“分组”行基于条件,因此必须在WHERE子句中,例如: WHERE l.LocationID = 5 AND inv.SerialNumber LIKE 'NA%'但是我不太确定在哪里放置它所以它不会将我的所有记录过滤到那些序列号如“NA%”

的记录

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

您应该可以使用以下内容:

;with cte as
(
  SELECT i.ItemDescription AS Desc, s.Name AS Manufacturer, inv.SerialNumber AS [Serial Number]
  FROM Assets a 
  LEFT OUTER JOIN Inventory inv ON a.InventoryID = inv.InventoryID 
  LEFT OUTER JOIN Items i ON inv.ItemID = i.ItemID 
  LEFT OUTER JOIN Rooms r ON a.RoomID = r.RoomID 
  LEFT OUTER JOIN Locations l ON r.LocationID = l.LocationID 
  LEFT OUTER JOIN Suppliers s ON i.ManufacturerID = s.SupplierID 
  WHERE l.LocationID = 5
),
totals as
(
  select [Desc], count(*) TotalCount
  from cte
  group by [desc]
)
select c.[desc],
  c.Manufacturer,
  case 
    when t.TotalCount > 1 
    then cast(t.TotalCount as varchar(50))
    else [Serial Number]
  end [Serial Number/Qnty]
from cte c
inner join totals t
  on c.[desc] = t.[desc]

答案 1 :(得分:0)

试试这个

;with cte as

(
    SELECT i.ItemDescription AS Desc, s.Name AS Manufacturer, 
    CASE WHEN isnull(inv.SerialNumber,'') like 'NA%' Then 'NA'
         Else inv.SerialNumber end AS [Serial Number]

     FROM Assets a 
     LEFT OUTER JOIN Inventory inv ON a.InventoryID = inv.InventoryID 
     LEFT OUTER JOIN Items i ON inv.ItemID = i.ItemID 
     LEFT OUTER JOIN Rooms r ON a.RoomID = r.RoomID 
     LEFT OUTER JOIN Locations l ON r.LocationID = l.LocationID 
     LEFT OUTER JOIN Suppliers s ON i.ManufacturerID = s.SupplierID 
     WHERE l.LocationID = 5

), cte2 as
(
     SELECT Desc, Manufacturer, [Serial Number], Count(*) cnt
     FROM cte2
     GROUP BY Desc, Manufacturer, [Serial Number]
)
SELECT Desc, Manufacturer, CASE WHEN isnull([Serial Number],'') = 'NA' 
                                THEN CAST(cnt as varchar)
                                else [Serial Number] end [Serial Number]
from cte2;