首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SQL压缩表-移除类似项

SQL压缩表-移除类似项
EN

Stack Overflow用户
提问于 2015-08-04 14:26:42
回答 1查看 35关注 0票数 0

拥有一个ID、IDLicense、Brand和ExtraBrands的表

IDLicense试图抓取所有类似的记录,合并所有记录,方法是获取IDLicense的所有副本,删除所有副本,但取品牌名称并将其添加到原始IDLicense中,并将已删除副本的品牌添加到ExtraBrands中。

到目前为止,我已经能够选择所有有重复的IDLicense。使用临时表存储所有额外信息。

代码语言:javascript
复制
INSERT INTO #TempTable (ID, IDLicense, Brand, ExtraBrands) 
SELECT ID, IDLicense, Brand, ExtraBrands FROM BrandOrders
WHERE IDLicense IN (SELECT IDLicense FROM BrandOrders GROUP BY IDLicense HAVING COUNT(*) > 1)

是否有一种简单的方法来代替使用临时表来代替删除所有类似的数据,并从副本中提取品牌并将它们添加为ExtraBrands?然后删除复本。

数据示例:

下表:

代码语言:javascript
复制
 1. IdLicense = 1, Brand="BlueBird", ExtraBrands is null
 2. IdLicense = 1, Brand="RedBird", ExtraBrands is null
 3. IdLicense = 1, Brand="YellowBird", ExtraBrands is null
 4. IdLicense = 2, Brand="BlueBird", ExtraBrands is null
 5. IdLicense = 2, Brand="RedBird", ExtraBrands is null

最后,它应该被压缩成

代码语言:javascript
复制
 1. IdLicense = 1, Brand="BlueBird", ExtraBrands = "RedBird YellowBird"
 2. IdLicense = 2, Brand="BlueBird", ExtraBrands = "RedBird"
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-04 15:45:16

您可以使用下面的代码来做您想做的事情,但是我建议不要对数据库进行这种去规范化。在一列中存储多个离散值会破坏关系模型,并经常导致各种问题。

相反,我建议您规范您的表,并使用如下所示的模式,其中有一个连接表,该表将许可实体与品牌实体连接起来:

代码语言:javascript
复制
CREATE TABLE BrandOrders (IdLicense int primary key);
CREATE TABLE Brands (BrandID int primary key, Brand varchar(20));
CREATE TABLE LicenseBrands (
    IdLicense int foreign key references BrandOrders, 
    BrandID int foreign key references Brands, 
    MainBrand bit,
    PRIMARY KEY (IdLicense, BrandId)
);

这既可以确保数据的完整性,又可以节省您的空间,而且使用起来也容易得多。

话虽如此,以下是用于“修复”数据的查询(更新,然后删除):

代码语言:javascript
复制
;with cte as (
    select *, r=row_number() over (partition by idlicense order by id) 
    from brandorders
    where idlicense in (
       select idlicense from brandorders group by idlicense having count(*) > 1
    )
)

update extern
set extrabrands = left(c , len(c)-1) 
from cte extern
cross apply
(
    select brand + ','
    from cte as intern
    where extern.idlicense = intern.idlicense and r > 1
    for xml path('')
) extrabrands (c)
where extern.r = 1;

delete from brandorders 
where idlicense in (
    select idlicense from brandorders group by idlicense having count(*) > 1
    ) 
  and extrabrands is null;

执行后的结果是,您的数据如下所示:

代码语言:javascript
复制
ID  IdLicense   Brand       ExtraBrands
1   1           BlueBird    RedBird,YellowBird
4   2           BlueBird    RedBird

示例SQL Fiddle

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31811993

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档