Sql server SQL:计算不同的值并合并相似的名称

Sql server SQL:计算不同的值并合并相似的名称,sql-server,tsql,sql-server-2014,Sql Server,Tsql,Sql Server 2014,语言:T-SQL 服务器:SQL Server 2014 我有一张电脑表,希望得到制造商对每台电脑的计数。这很简单,但是当从每台电脑中提取数据时,一些较旧的HP计算机将其制造商称为“惠普”,而较新的机器则将其制造商称为“HP”。我想把这些组合成“HP”。不进行任何替换/组合的查询如下所示: SELECT DISTINCT f_assetmanufacturer AS 'Manufacturer', COUNT(DISTINCT f_assettagID) AS 'Number

语言:T-SQL
服务器:SQL Server 2014

我有一张电脑表,希望得到制造商对每台电脑的计数。这很简单,但是当从每台电脑中提取数据时,一些较旧的HP计算机将其制造商称为“惠普”,而较新的机器则将其制造商称为“HP”。我想把这些组合成“HP”。不进行任何替换/组合的查询如下所示:

SELECT 
    DISTINCT f_assetmanufacturer AS 'Manufacturer',
    COUNT(DISTINCT f_assettagID) AS 'Number of Each'
FROM tb_assets
GROUP BY f_assetmanufacturer
基于当前查询的示例输出:

Manufacturer      Number of Each
Dell Inc.         10
Hewlett-Packard   6
HP                6
期望输出:

Manufacturer      Number of Each
Dell Inc.         10
HP                12

如何重写查询以合并“HP”和“Hewlett-Packard”计数?

您可以使用
CASE
语句。根据需要添加尽可能多的附加case子句

SELECT 
    CASE f_assetmanufacturer 
    WHEN 'Hewlett-Packard' THEN 'HP'
    ELSE f_assetmanufacturer 
    END
, COUNT(DISTINCT f_assettagID)
FROM dbo.Code c
GROUP BY CASE f_assetmanufacturer 
    WHEN 'Hewlett-Packard' THEN 'HP'
    ELSE f_assetmanufacturer 
    END

使用“制造商”列上的“替换”获取所需的格式化字符串

SELECT COUNT(*), REPLACE(Mfg, 'Hewlett-Packard', 'HP')
FROM dbo.SO41271540
GROUP BY REPLACE(Mfg, 'Hewlett-Packard', 'HP')

此查询将完成此任务,但它是硬编码的:

SELECT 
    DISTINCT REPLACE(f_assetmanufacturer, 'Hewlett-Packard', 'HP') AS 'Manufacturer',
    COUNT(DISTINCT f_assettagID) AS 'Number of Each'
FROM tb_assets
GROUP BY f_assetmanufacturer

更好的解决方案是有一个可以加入的“主”制造商查找表,以及一个可以引用的
tb_assets
(例如ManufacturerId)中的外键列。

我会选择一个映射表,只是为了不让它出现在代码中,随着时间的推移,它会变得更加动态。例如:

Declare @YourResults table (Manufacturer varchar(50),[Number of Each] int)
Insert into @YourResults values
('Dell Inc.',         10),
('Hewlett-Packard',   6),
('HP',                6)

Declare @Maping table (MapFrom varchar(50),MapTo varchar(50))
Insert Into @Maping values 
('Hewlett-Packard','HP'),
('Hewlett-Packard Inc.','HP')


Select Manufacturer= IsNull(B.MapTo,Manufacturer)
      ,[Number of Each] = sum([Number of Each])
 From  @YourResults A
 Left Join  @Maping B on (MapFrom=A.Manufacturer)
 Group By IsNull(B.MapTo,Manufacturer)
返回

Manufacturer    Number of Each
Dell Inc.       10
HP              12

谢谢,这似乎有效。我曾尝试在SELECT语句中使用“Replace”,但它仍然只返回“6”而不是“12”。我没有意识到这也是团体声明中的要求。你能解释一下这个选项是否比下面@jhilden的响应更可取,而不是更短吗?如果你需要执行一次替换,我的解决方案会更简单。如果需要替换多个名称,则需要链接replace语句。在这种情况下,@jhilden的解决方案将更加优雅。如果您需要定期更新制造商映射,那么按照John Cappelletti的建议创建映射表会更好。使用最简单的工具完成工作。幸运的是,扩大替换数量的必要性非常小。目前只有“HP”和“Hewlett-Packard”是相同的,尽管数据库目前在5000多台PC上有24家不同的制造商。其他制造商在向操作系统报告自己的方式上似乎都是一致的。@Beem这是一个非常有效的快速修复解决方案。但根据我的经验,如果某些事情能够改变,它最终会改变。今天是惠普,明天可能是东芝。你真的想追那只猫吗?@John我有大约10年的数据,我只能找到“HP”和“Hewlett-Packard”的问题。虽然其他制造商更改名称的可能性始终存在,但从历史上看,这并不是一个问题,如果我注意到一种模式,我将很乐意创建一个映射表来帮助将来的查询。幸运的是,扩大替换数量的必要性非常小。目前只有“HP”和“Hewlett-Packard”是相同的,尽管数据库目前在5000多台PC上有24家不同的制造商。其他制造商在向操作系统报告自己的方式上似乎都是一致的。而为了这个查询,我可能不必将其扩展到“HP”和“Hewlett-Packard”的组合之外,你在这里的例子很有见地,因为我可以想到很多其他用途,在不久的将来我可能会遇到类似的问题。谢谢您深思熟虑的回复。@Beems,这很公平。我只是想让你知道。快速报道。我的一位客户引入了一个新的风险评级6W(或者说6.5),他们必须审查数千份报告和无数行代码。另一方面,我只需要在映射表中添加一条记录。