【问题标题】:JOIN with GROUP BY causing SUM() logic issues加入 GROUP BY 导致 SUM() 逻辑问题
【发布时间】:2017-03-06 09:32:02
【问题描述】:

查询-

sel TableName, DatabaseName, sum(CurrentPerm/(1024*1024*1024)) as Size_in_GB
        from dbc.tablesize
        group by 1,2
        order by GB desc

结果-

+-----------+--------+------------+
| TableName | DBName | Size_in_GB |
+-----------+--------+------------+
| WRP       | A      |  28,350.01 |
| CPC       | B      |  19,999.37 |
| SDF       | C      |  13,263.67 |
| DB1400    | D      |  13,200.26 |
+-----------+--------+------------+

从上面的简单查询我可以看到 数据库 A 的表 WRP 接近 28350 GB

现在我正在尝试加入另一个表 dbc.indices 以使用列 IndexType 进行过滤,但现在所有表的 Size_in_GB 都发生了变化。

sel a.TableName,a.DatabaseName, sum(CurrentPerm/(1024*1024*1024)) as Size_in_GB from dbc.tablesize a
join dbc.indices b on a.TableName = b.TableName and a.DatabaseName=b.DatabaseName
--where b.indexType='P'
group by 1,2
order by Size_in_GB desc

结果是这样的-

+-----------+--------+------------+
| TableName | DBName | Size_in_GB |
+-----------+--------+------------+
| WRP       | A      |  56,700.02 |
| CPC       | B      |  39,998.74 |
| DB1400    | D      |  39,600.78 |
+-----------+--------+------------+

现在同一个表的大小是原来的两倍,即 WRP56700 GB。 (其他表类似)

我不确定我用于加入的逻辑有什么问题。

P.S - 我的目标是找到所有大小超过 100GB 且 indexType 为 'P' 的表

编辑 - 共享 DBC.INDICES 表中的相关列

+--------------+------------+-------------+-----------+------------+---------------+------------+----------------+
| DatabaseName | TableName  | IndexNumber | IndexType | UniqueFlag |   IndexName   | ColumnName | ColumnPosition |
+--------------+------------+-------------+-----------+------------+---------------+------------+----------------+
| Some DB      | Some Table |           1 | P         | N          | IndexNamehere | ColumnA    |              1 |
+--------------+------------+-------------+-----------+------------+---------------+------------+----------------+

【问题讨论】:

  • 索引表是什么样子的?
  • SELECT Distinct 会帮助你

标签: sql join teradata


【解决方案1】:

什么令人困惑?

您显然拥有具有多个索引的表。每个索引都会导致表格出现多次以进行聚合。

为了你想要的:

我的目标是找到所有大于 100GB 的表 并将 indexType 设为 'P'

我建议将索引比较移至where 子句:

select t.TableName, t.DatabaseName,
       sum(tCurrentPerm/(1024*1024*1024)) as Size_in_GB
from dbc.tablesize t
where exists (select 1
              from dbc.indices i
              where t.TableName = i.TableName and t.DatabaseName = i.DatabaseName and
                    i.indexType = 'P'
             )
group by 1,2
order by Size_in_GB desc

如果您还想添加该过滤器,您可以在order by 之前添加having Size_in_GB > 100

【讨论】:

  • 我真的很喜欢你的回答,你能详细点吗?
【解决方案2】:

您的密钥可能在dbc.indices 表中重复。对于单个 TableNamedbc.indices 表有多个条目,因此当您加入 dbc.tablesize 表时记录被重复,因此 SUM 应用于重复记录,因此计算错误。

试试这个方法

SELECT a.TableName,
       a.DatabaseName,
       Sum(CurrentPerm / ( 1024 * 1024 * 1024 )) AS Size_in_GB
FROM   dbc.tablesize a
       JOIN (SELECT DISTINCT b.TableName,
                             b.DatabaseName
             FROM   dbc.indices b
             --where b.indexType='P'
             ) b
         ON a.TableName = b.TableName
            AND a.DatabaseName = b.DatabaseName

GROUP  BY a.TableName,
          a.DatabaseName
ORDER  BY Size_in_GB DESC 

【讨论】:

  • 你的回答成功了!您能否详细说明“重复密钥”的确切含义以及它的影响?
  • @PirateX - 现在更新检查.. 如果你还是不明白,我的英语有点差.. 告诉我会添加一个演示
【解决方案3】:

P.S - 我的目标是找到所有大于 100GB 的表 在 Size 中,并且 indexType 为 'P'

如果您只想查找存在索引的某些表,则根本不应该加入。请改用EXISTS。这会将您的条件置于其所属的 WHEREHAVING 子句中,并且您的条件复制记录没有问题(在您的情况下:当表具有多个匹配索引时不再重要)。

select tablename, databasename, sum(currentperm/(1024*1024*1024)) as size_in_gb 
from dbc.tablesize ts
group by tablename, databasename
having sum(currentperm/(1024*1024*1024)) > 100
and exists
(
  select *
  from dbc.indices i
  where i.tablename = ts.tablename and i.databasename = ts.databasename
  and i.indexType = 'P'
)
order by Size_in_GB desc;

【讨论】:

    【解决方案4】:

    dbc.IndidesV(永远不要使用旧的已弃用的非 V 视图)每个索引每列有一行。

    您可以简单地添加一个条件以将其限制为单行:where IndexType = 'P' and ColumnPosition = 1

    并且进行早期聚合更有效,即在加入之前进行聚合:

    select t.*
    from 
     (
       select TableName, DatabaseName,
          sum(CurrentPerm/(1024*1024*1024)) as Size_in_GB
       from dbc.TableSizeV
       group by 1,2
       having Size_in_GB > 100
     ) as dt
    join dbc.IndicesV b 
      on a.TableName = b.TableName
     and a.DatabaseName=b.DatabaseName
    where IndexType = 'P' 
      and ColumnPosition = 1
    order by Size_in_GB desc;
    

    但是你为什么要过滤那个IndexType=P,你不关心大于100GB的其他对象(NoPI/列式表,连接索引)吗?顺便说一句,这不会返回所有带有 PI 的表,只有 IndexNumber=1 会。

    根据您的需要,您最好加入dbc.TablesV

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多