mssql子查询聚合 - 总和错误

时间:2017-01-03 13:13:26

标签: sql sql-server tsql

所以我试图在tsql(MSSQL2014)中获取一些数据,其中我使用子查询来获取一些外键数据表的总和。

结构如下:

TABLE [AggregateData](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Aggregate_UUID] [uniqueidentifier] NOT NULL,
    [DataDate] [date] NOT NULL,
    [SizeAvailable] [bigint] NOT NULL,
    [SizeTotal] [bigint] NOT NULL,
    [SizeUsed] [bigint] NOT NULL,
    [PercentageUsed] [int] NOT NULL
)

TABLE [Aggregate](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [UUID] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](255) NOT NULL,
    [Cluster_UUID] [uniqueidentifier] NOT NULL,
    [DiskTypeID] [int] NOT NULL
)

TABLE [DiskType](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [TypeName] [nvarchar](255) NULL
)

TABLE [Volume](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [UUID] [uniqueidentifier] NOT NULL,
    [Name] [nvarchar](255) NOT NULL,
    [Aggregate_UUID] [uniqueidentifier] NOT NULL,
    [ServiceClassID] [int] NULL,
    [ProtocolID] [int] NOT NULL,
    [EnvironmentID] [int] NOT NULL
)

TABLE [VolumeData](
    [Id] [bigint] IDENTITY(1,1) NOT NULL,
    [Volume_UUID] [uniqueidentifier] NOT NULL,
    [DataDate] [date] NOT NULL,
    [SizeAvailable] [bigint] NOT NULL,
    [SizeTotal] [bigint] NOT NULL,
    [SizeUsed] [bigint] NOT NULL,
    [PercentageUsed] [int] NOT NULL
)

现在最后我需要获得以下数据:

DataDate,DiskType,AggregateSizes(可用,已用,总计),汇总的卷大小(可用的总和,已用,该聚合中的总量)

我在考虑使用子查询,但在尝试仅获取特定聚合的值时(为了测试,我更容易检查),我在子查询中得到错误的值。

这是我尝试过的;

SELECT
  AggregateData.DataDate,
  AggregateData.SizeTotal AS AggregateSizeTotal,
  (SELECT
    SUM(VolumeData.SizeTotal)
  FROM VolumeData
  LEFT JOIN Volume
    ON VolumeData.Volume_UUID = Volume.UUID
  WHERE Aggregate_UUID = Volume.Aggregate_UUID
  AND VolumeData.DataDate = AggregateData.DataDate)
  VolumeSizeTotal

FROM AggregateData

WHERE AggregateData.Aggregate_UUID = 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C'
ORDER BY AggregateData.DataDate

但是这似乎是我得不到子查询总和的正确值。我的子查询总和很高,所以我假设我的where子句不正确(或整个设置;)...)

  • 所以,问题1.子查询是否可行?或者我应该采用不同的方式吗?
  • 如果(问题1 == true)我的子查询有什么问题?

3 个答案:

答案 0 :(得分:1)

您需要限定所有列名称。我建议使用表格缩写。问题是Aggregate_UUID = v.Aggregate_UUID。第一列来自v,所以这(基本上)是一个无操作。

据推测,您希望这与外部查询相关:

SELECT ad.DataDate, ad.SizeTotal AS AggregateSizeTotal,
       (SELECT SUM(vd.SizeTotal)
        FROM VolumeData vd LEFT JOIN
             Volume v
             ON vd.Volume_UUID = v.UUID
        WHERE ad.Aggregate_UUID = v.Aggregate_UUID AND
              ad.DataDate = vd.DataDate
       ) VolumeSizeTotal
FROM AggregateData ad
WHERE ad.Aggregate_UUID = 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C'
ORDER BY ad.DataDate

答案 1 :(得分:0)

您可以使用JOIN而不是相关子查询(O(n ^ 2)性能)来执行此操作 -

SELECT
  t1.DataDate,
  t1.SizeTotal AS AggregateSizeTotal,
  t2.total VolumeSizeTotal
FROM AggregateData t1 left join (SELECT
    DataDate, SUM(VolumeData.SizeTotal) total
  FROM VolumeData
  LEFT JOIN Volume
    ON VolumeData.Volume_UUID = Volume.UUID
  WHERE Aggregate_UUID = Volume.Aggregate_UUID
  group by DataDate) t2 on t1.datadate = t2.dataDate
WHERE t1.Aggregate_UUID = 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C';

答案 2 :(得分:0)

要查询以返回所需的最终结果,我会使用以下内容:

  

现在最后我需要获取以下数据: DataDate,DiskType,AggregateSizes(可用,已用,总计),聚合的卷大小(可用的总和,已使用的,该聚合中的卷总数)

select 
      AggregateUuid          = a.uuid
    , DiskType               = dt.TypeName
    , DataDate               = ad.DataDate
    , AggregateSizeAvailable = ad.SizeAvailable
    , AggregateSizeUsed      = ad.SizeUsed
    , AggregateSizeTotal     = ad.SizeTotal
    , VolumeSizeAvailable    = sum(vd.SizeAvailable)
    , VolumeSizeUsed         = sum(vd.SizeUsed)
    , VolumeSizeTotal        = sum(vd.SizeTotal)
  from [Aggregate] a
      inner join DiskType      dt  on dt.Id             = a.DiskTypeId
      inner join AggregateData ad  on ad.Aggregate_uuid = a.uuid
      left  join Volume         v  on  v.Aggregate_uuid = a.uuid 
      left  join VolumeData     vd on vd.Volume_uuid    = v.uuid
                                 and vd.DataDate       = ad.DataDate
  where a.uuid = 'C58D0098-D1A4-4ee9-A0E9-7de3eeb6275C'
  group by 
      a.uuid
    , dt.TypeName
    , ad.DataDate
    , ad.SizeAvailable
    , ad.SizeUsed
    , ad.SizeTotal
  order by a.uuid, ad.DataDate;

测试设置:http://rextester.com/HZZHLI45077

create table DiskType(
    Id int identity(1,1) not null
  , TypeName nvarchar(255) null
);
set identity_insert DiskType on;
insert into DiskType (Id, TypeName) values 
  (1,'Type1'), (2,'Type2');
set identity_insert DiskType off;

create table [Aggregate](
    Id bigint identity(1,1) not null
  , uuid uniqueidentifier not null
  , Name nvarchar(255) not null
  , Cluster_uuid uniqueidentifier not null
  , DiskTypeid int not null 
);

insert into [Aggregate] (uuid, name, cluster_uuid, disktypeid) 
            select 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', 'ex', newid(), 1;

create table AggregateData(
    Id bigint identity(1,1) not null
  , Aggregate_uuid uniqueidentifier not null
  , DataDate date not null
  , SizeAvailable bigint not null
  , SizeTotal bigint not null
  , SizeUsed bigint not null
  , PercentageUsed int not null
);

insert into AggregateData 
            select 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', '20170101', 12,100,87,87
  union all select 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', '20170102', 9,100,90,90
  union all select 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', '20170103', 6,100,93,93;

create table Volume(
    Id bigint identity(1,1) not null
  , uuid uniqueidentifier not null
  , Name nvarchar(255) not null
  , Aggregate_uuid uniqueidentifier not null
  , ServiceClassid int null
  , Protocolid int not null
  , Environmentid int not null
);
insert into Volume 
            select '00000000-0000-0000-0000-000000000001', 'v1'
                , 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', null, 1, 1
  union all select '00000000-0000-0000-0000-000000000002', 'v2'
                , 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', null, 1, 1
  union all select '00000000-0000-0000-0000-000000000003', 'v3'
                , 'C58D0098-D1A4-4EE9-A0E9-7DE3EEB6275C', null, 1, 1;

create table VolumeData(
    Id bigint identity(1,1) not null
  , Volume_uuid uniqueidentifier not null
  , DataDate date not null
  , SizeAvailable bigint not null
  , SizeTotal bigint not null
  , SizeUsed bigint not null
  , PercentageUsed int not null
);

insert into VolumeData 
            select '00000000-0000-0000-0000-000000000001', '20170101', 4,33,29,88
  union all select '00000000-0000-0000-0000-000000000002', '20170101', 4,33,29,88
  union all select '00000000-0000-0000-0000-000000000003', '20170101', 4,34,29,87
  union all select '00000000-0000-0000-0000-000000000001', '20170102', 3,33,30,91
  union all select '00000000-0000-0000-0000-000000000002', '20170102', 3,33,30,91
  union all select '00000000-0000-0000-0000-000000000003', '20170102', 3,34,30,90
  union all select '00000000-0000-0000-0000-000000000001', '20170103', 2,33,31,94
  union all select '00000000-0000-0000-0000-000000000002', '20170103', 2,33,31,94
  union all select '00000000-0000-0000-0000-000000000003', '20170103', 2,34,31,93

go
/* -------------------------------------------------------- */

select 
      AggregateUuid          = a.uuid
    , DiskType               = dt.TypeName
    , DataDate               = convert(varchar(10),ad.DataDate,121)
    , AggregateSizeAvailable = ad.SizeAvailable
    , AggregateSizeUsed      = ad.SizeUsed
    , AggregateSizeTotal     = ad.SizeTotal
    , VolumeSizeAvailable    = sum(vd.SizeAvailable)
    , VolumeSizeUsed         = sum(vd.SizeUsed)
    , VolumeSizeTotal        = sum(vd.SizeTotal)
  from [Aggregate] a
      inner join DiskType      dt  on dt.Id             = a.DiskTypeId
      inner join AggregateData ad  on ad.Aggregate_uuid = a.uuid
      left  join Volume         v  on  v.Aggregate_uuid = a.uuid 
      left  join VolumeData     vd on vd.Volume_uuid    = v.uuid
                                 and vd.DataDate       = ad.DataDate
  where a.uuid = 'C58D0098-D1A4-4ee9-A0E9-7de3eeb6275C'
  group by 
      a.uuid
    , dt.TypeName
    , ad.DataDate
    , ad.SizeAvailable
    , ad.SizeUsed
    , ad.SizeTotal
  order by a.uuid, ad.DataDate;

结果:

+--------------------------------------+----------+------------+------------------------+-------------------+--------------------+---------------------+----------------+-----------------+
|            AggregateUuid             | DiskType |  DataDate  | AggregateSizeAvailable | AggregateSizeUsed | AggregateSizeTotal | VolumeSizeAvailable | VolumeSizeUsed | VolumeSizeTotal |
+--------------------------------------+----------+------------+------------------------+-------------------+--------------------+---------------------+----------------+-----------------+
| c58d0098-d1a4-4ee9-a0e9-7de3eeb6275c | Type1    | 2017-01-01 |                     12 |                87 |                100 |                  12 |             87 |             100 |
| c58d0098-d1a4-4ee9-a0e9-7de3eeb6275c | Type1    | 2017-01-02 |                      9 |                90 |                100 |                   9 |             90 |             100 |
| c58d0098-d1a4-4ee9-a0e9-7de3eeb6275c | Type1    | 2017-01-03 |                      6 |                93 |                100 |                   6 |             93 |             100 |
+--------------------------------------+----------+------------+------------------------+-------------------+--------------------+---------------------+----------------+-----------------+