SQL Server 2018如何将信息分组到不同的列中
我有一张桌子的格式非常混乱。这是表中间列的快照,这就是为什么数据中有大洞,其他列中有这些行的内容SQL Server 2018如何将信息分组到不同的列中,sql,sql-server,group-by,Sql,Sql Server,Group By,我有一张桌子的格式非常混乱。这是表中间列的快照,这就是为什么数据中有大洞,其他列中有这些行的内容 +---------------+--------------------+--------------+--------------+ | upsell1 | upsell2 | upsell3 | upsell4 | +---------------+--------------------+--------------+----------
+---------------+--------------------+--------------+--------------+
| upsell1 | upsell2 | upsell3 | upsell4 |
+---------------+--------------------+--------------+--------------+
| | | Car Kit | Scented Tabs |
| | | | |
| | | | |
| | Fiters | | |
| NULL | NULL | NULL | NULL |
| | | | |
| | Car Kit | Scented Tabs | |
| | | | |
| | | | |
+---------------+--------------------+--------------+--------------+
我希望得到一个输出,对每个产品进行分组和计数,无论它出现在哪个列中
+--------------+---------------+
| Product | Product Count |
+--------------+---------------+
| Car Kit | 2 |
| Scented Tabs | 2 |
| Fiters | 1 |
+--------------+---------------+
通常情况下,如果它都在一列中,那么使用group by命令将X作为列1,countX作为列2是很容易的,但是我正在寻找一种方法来将这些不同的信息正确地分组在一起
注意:如果您无法控制糟糕的模式,我无法对表的结构进行太多更改,这让我很懊恼
with CTE as
(
select upsell1 as product, 1 as counter
from MyTable
where upsell1 is not null
union all
select upsell2, 1
from MyTable
where upsell2 is not null
union all
select upsell3, 1
from MyTable
where upsell3 is not null
union all
select upsell4, 1
from MyTable
where upsell4 is not null
)
select product, sum(counter)
from CTE
group by product
试试这个
declare @test table (
upsell1 varchar(100),
upsell2 varchar(100),
upsell3 varchar(100),
upsell4 varchar(100)
)
insert into @test values ('','','Car Kit','Scented Tabs')
insert into @test values ('','','','')
insert into @test values ('','','','')
insert into @test values ('','Fiters','','')
insert into @test values (null,null,null,null)
insert into @test values ('','','','')
insert into @test values ('','Car Kit','Scented Tabs','')
insert into @test values ('','','','')
insert into @test values ('','','','')
select
abc,
count(*)
from (
select *
from @test) as src
unpivot (
abc for anyThing in (upsell1,upsell2,upsell3,upsell4)
) as ttt
group by abc
由于没有类型假设,我会选择使用UNPIVOT的安全方法:
SELECT * INTO #t FROM (VALUES
('','','Car Kit','Scented Tabs'),
('','','',''),
('','','',''),
('','Fiters','',''),
(null,null,null,null),
('','','',''),
('','Car Kit','Scented Tabs',''),
('','','',''),
('','','','')
) T(upsell1,upsell2,upsell3,upsell4)
SELECT Product, COUNT(Product) [Product Count] FROM
(
SELECT
CAST(upsell1 AS nvarchar(MAX)) upsell1,
CAST(upsell2 AS nvarchar(MAX)) upsell2,
CAST(upsell3 AS nvarchar(MAX)) upsell3,
CAST(upsell4 AS nvarchar(MAX)) upsell4
FROM #t
) T
UNPIVOT (Product for X IN (upsell1,upsell2,upsell3,upsell4)) P
WHERE Product != ''
GROUP BY Product
结果
我将使用apply来完成此操作:
你的问题有点不清楚空格是什么。您可能需要:
where v.upsell is not null and v.upsell <> ''
甚至:
where v.upsell is not null and ltrim(rtrim(v.upsell)) <> ''
正如您所发现的,由于非规范化设计,您正在与此进行斗争。您必须将这些列转换为行UNPIVOT或UNION,然后进行标准计数。示例中的空格是空字符串还是空字符串?空字符串是空字符串,但也有空字符串出于某些疯狂的原因。请给它一个别名Product count如果在多个upsell中有相同的数据,此计数是否同时计数场?@tomdemaine是的。Union all不会从结果中删除重复项。也就是说,戈登有更好的解决方案
where v.upsell is not null and v.upsell <> ''
where v.upsell is not null and ltrim(rtrim(v.upsell)) <> ''