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

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

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

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

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

美国:2加拿大:1

我尝试了以下方法:

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

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

【问题讨论】:

  • 表格中有多少层嵌套?
  • 仅 2:国家和地区

标签: sql sql-server sql-server-2008


【解决方案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 谢谢。我已经做出了改变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-24
    • 2017-03-04
    • 2013-11-27
    • 1970-01-01
    • 2011-09-19
    • 1970-01-01
    相关资源
    最近更新 更多