我正在尝试检索事实表中的所有主键,然后计算该事实表中按该id分组的记录数,但到目前为止,我似乎只能得到所有主键及其表。我想我需要做一些子查询
SELECT
tab1.name AS [FactTable],
col1.name AS [PrimaryKey]
FROM sys.indexes ind1
INNER JOIN sys.tables tab1
ON tab1.object_id = ind1.object_id
INNER JOIN sys.schemas sch1
ON tab1.schema_id = sch1.schema_id
INNER JOIN sys.columns col1
ON col1.object_id = tab1.object_id AND col1.name like '%Id'
WHERE tab1.name like 'Fact%' AND ind1.is_primary_key = 1
示例输出
primaryKey countRecordsGroupedByPrimaryKey
2 4000
3 8343
4 203
1 4023
答案 0 :(得分:0)
如果我正确理解了这个问题,你想根据一些标准计算某些表中的所有行。不确定为什么你关心主键部分,因为根据定义,主键必须是唯一的,所以这仍然可以简化为不检查主键但是无论如何。
我确实删除了对sys.columns的连接,因为除非您只想要名为Fact%的表并且有一个名为%Id的列,否则为什么它与列的名称有关。
根据我的理解,这应该让你非常接近。
declare @SQL nvarchar(max) = ''
select @SQL = @SQL + 'select TableName = ''' + tab1.name + ''', NumRows = count(*) from ' + QUOTENAME(sch1.name) + '.' + QUOTENAME(tab1.name) + ' UNION ALL '
FROM sys.indexes ind1
INNER JOIN sys.tables tab1
ON tab1.object_id = ind1.object_id
INNER JOIN sys.schemas sch1
ON tab1.schema_id = sch1.schema_id
--INNER JOIN sys.columns col1
-- ON col1.object_id = tab1.object_id AND col1.name like '%Id'
WHERE tab1.name like 'Fact%'
AND ind1.is_primary_key = 1
select @SQL = LEFT(@SQL, LEN(@SQL) - 10) + ' ORDER BY TableName'
select @SQL --uncomment the exec line below once you are comfortable that the dynamic sql is what you want.
--exec sp_executesql @SQL
答案 1 :(得分:0)
我走出困境,猜测你要计算事实表中使用的每个dimensionPK的数量。如果事实表引用了两个不同的维度,则需要两个不同的语句来计算该维度的使用情况。
对于下面的查询,请提供您的事实表名称和架构,它应该生成一个计数语句,用于连接您的事实,并通过连接键进行调暗和分组。
- 如果事实表有两种不同的FK关系,您将得到两种不同的陈述
- 如果表使用复合PK,则两个键列都将包含在连接
这很复杂,我没有任何有多个FK的桌子来测试它,所以请告诉我它是否符合你的要求。
DECLARE @NameOfTableWithFKs sysname = 'your fact table name',
@SchemaOfTableWithFKs sysname = 'dbo';
WITH JoinColumns
AS (SELECT QUOTENAME(OBJECT_SCHEMA_NAME(parent.object_id)) + '.' + QUOTENAME(OBJECT_NAME(parent.object_id)) AS ParentTableName,
QUOTENAME(OBJECT_SCHEMA_NAME(referenced.object_id)) + '.' + QUOTENAME(OBJECT_NAME(referenced.object_id)) AS ReferencedTableName,
QUOTENAME(OBJECT_NAME(parent.object_id)) + '.' + QUOTENAME(parent.name) + ' = ' + QUOTENAME(OBJECT_NAME(referenced.object_id)) + '.'
+ QUOTENAME(referenced.name) AS JoinColumn,
QUOTENAME(OBJECT_NAME(referenced.object_id)) + '.' + QUOTENAME(referenced.name) AS GroupingColumn
FROM sys.foreign_key_columns AS fkc
INNER JOIN sys.columns AS parent
ON parent.object_id = fkc.parent_object_id
AND parent.column_id = fkc.parent_column_id
INNER JOIN sys.columns AS referenced
ON referenced.object_id = fkc.referenced_object_id
AND referenced.column_id = fkc.referenced_column_id
WHERE OBJECT_NAME(parent.object_id) = @NameOfTableWithFKs
AND OBJECT_SCHEMA_NAME(parent.object_id) = @SchemaOfTableWithFKs
),
JoinTables
AS (SELECT QUOTENAME(OBJECT_SCHEMA_NAME(tbl.object_id)) + '.' + QUOTENAME(OBJECT_NAME(tbl.object_id)) AS ParentTableName,
QUOTENAME(OBJECT_SCHEMA_NAME(rtbl.object_id)) + '.' + QUOTENAME(OBJECT_NAME(rtbl.object_id)) AS ReferencedTableName
FROM sys.tables AS tbl
INNER JOIN sys.foreign_keys AS cstr
ON cstr.parent_object_id = tbl.object_id
INNER JOIN sys.tables AS rtbl
ON rtbl.object_id = cstr.referenced_object_id
WHERE OBJECT_NAME(tbl.object_id) = @NameOfTableWithFKs
AND OBJECT_SCHEMA_NAME(tbl.object_id) = @SchemaOfTableWithFKs
)
SELECT 'SELECT Count(*)' + ( SELECT ', ' + JC.GroupingColumn
FROM JoinColumns AS JC
WHERE JC.ParentTableName = jt.ParentTableName
AND JC.ReferencedTableName = jt.ReferencedTableName
FOR XML PATH('')
) + ' FROM ' + JT.ParentTableName + ' INNER JOIN ' + JT.ReferencedTableName + ' ON'
+ SUBSTRING(( SELECT ' AND ' + JC.JoinColumn
FROM JoinColumns AS JC
WHERE JC.ParentTableName = JT.ParentTableName
AND JC.ReferencedTableName = JT.ReferencedTableName
FOR XML PATH('')
), 5, 8000
) + ' GROUP BY ' + SUBSTRING(( SELECT ', ' + JC.GroupingColumn
FROM JoinColumns AS JC
WHERE JC.ParentTableName = JT.ParentTableName
AND JC.ReferencedTableName = JT.ReferencedTableName
FOR XML PATH('')
), 2, 8000
)
FROM JoinTables AS JT;