在引用自身的表上创建计数

Posted

技术标签:

【中文标题】在引用自身的表上创建计数【英文标题】:Create Count On Table That References Itself 【发布时间】:2017-03-03 14:42:35 【问题描述】:

我有一个如下所示的表格:

该表列出了这些国家/地区内的国家和地区(州、省、县等)。我需要对所有国家/地区的所有地区进行计数。如您所见,每个地区都有一个ParentID,即您可以在其中找到该地区的国家/地区的ID

例如,加利福尼亚在美国,因此其父 ID 为 1(即美国的 ID)。

所以,上面简单表格的结果应该是:

美国:2加拿大:1

我尝试了以下方法:

    将所有值选择到具有ID a 1 的表中(对于美国) 将所有值选择到具有ID a 3 的表中(对于加拿大) 将Parent ID 为 1 的所有值选择到 USA 表中 选择加拿大表中的所有值,Parent ID 为 3 在两张表上都算数

上述方法的问题是,如果添加一个新的国家,将不会自动生成一个计数。 有什么想法让这个更有活力吗?

【问题讨论】:

表格中有多少层嵌套? 仅 2:国家和地区 【参考方案1】:

你必须自己加入表:

select  t1.ID, t1.segment, count(distinct t2.ID)
from    yourTable t1
join    yourTable t2
on      t1.ID = t2.parentID
where   t1.parentID is null
group by t1.ID, t1.segment

where 子句确保您只显示“***”行。

【讨论】:

感谢@Stefano Zanini,但这仅提供***行的计数。我要计数顶层 + 子层 您的问题指出“我需要生成所有国家/地区内所有地区的计数”,这是有道理的,因为如果级别只是国家和地区,那么地区级别的计数将始终为 1 . 如果你也想显示区域级别的计数,你所要做的就是删除 where 子句。【参考方案2】:

也许重新格式化数据是有意义的,因为除了国家和地区的计数之外,您还想进行其他类型的查询。

    CREATE TABLE #CountriesRegions
(
    [ID] [int] NOT NULL,
    parentid [int]  NULL,
    segment [nvarchar](50)  NULL) 

insert into #CountriesRegions values (1,null,'usa'), (2,1, 'california'), (3, null, 'canada'), (4, 3, 'quebec'), (5, 1, 'NY')

select * from #CountriesRegions

Create table #Country
([ID] [int] NOT NULL
,[country_name] [nvarchar](50) NOT NULL)

Insert into #Country select ID, segment AS country_name from #CountriesRegions where parentid IS NULL

select * from #Country

Create table #Region
([ID] [int] NOT NULL
,[country_id] [int] NOT NULL
,[region_name] [nvarchar](50) NOT NULL)

Insert into #Region select ID, parentid AS country_ID, segment AS region_name from #CountriesRegions where parentid IS NOT NULL

select * from #Region

Select COUNT(*) As 'Num of Countries' from #Country
Select COUNT(*) As 'Num of Regions' from #Region

【讨论】:

【参考方案3】:
CREATE TABLE CountriesRegions
(
    [ID] [int] NOT NULL,
    parentid [int]  NULL,
    segment [nvarchar](50)  NULL) 

insert into CountriesRegions values (1,null,'usa'), (2,1, 'california'), (3, null, 'canada'), (4, 3, 'quebec'), (5, 1, 'NY')

select a.id, a.segment, count(*) as [Region Count]
from CountriesRegions a
left join CountriesRegions b
on a.id=b.parentid
where b.id is not null
group by a.id, a.segment

【讨论】:

我认为 (1,1,'usa') 应该是 (1,null,'usa') 以匹配 OP 的表。但是我无法提交这么小的修改(少于 6 个字符的更改)。 @Degan 谢谢。我已经做出了改变。

以上是关于在引用自身的表上创建计数的主要内容,如果未能解决你的问题,请参考以下文章

在刚刚创建的表上插入覆盖

在过程中动态添加的表上创建触发器

在已有大量数据的表上创建 MySQL 索引

mysql在具有1亿行的表上创建索引

在基于临时会话的表上创建索引后运行统计信息

在包含数百万行和多个过滤器的表上创建哪些索引