2015-07-21 50 views
1

我正在使用SQL Server 2008并希望从数据库中的所有表中获取列的总行数。为特定列和列值计算所有表的行

这是我的样本数据

表1

T1Id  Name 
1   XCV 
2   ASD 
3   GHJ 

表2

T2Id  T1Id  Name 
    1   1   TYU 
    2   1   BBB 
    3   2   LLL 
    4   1   JJJ 
    5   1   LKM 
    6   2   POI 

表3

T3Id  T1Id  Name 
    1   3   DDS 
    2   3   BSS 
    3   2   SQA 
    4   2   FWF 
    5   1   IKM 
    6   2   PLO 

我有表4,但也不想在结果中添加数

我想

SELECT  TOP (100) PERCENT ta.name AS TableName, SUM(pa.rows) AS RowCnt 
FROM   sys.tables AS ta LEFT OUTER JOIN 
         sys.partitions AS pa ON pa.object_id = ta.object_id LEFT OUTER JOIN 
         sys.schemas AS sc ON ta.schema_id = sc.schema_id LEFT OUTER JOIN 
         INFORMATION_SCHEMA.COLUMNS ON ta.name = INFORMATION_SCHEMA.COLUMNS.TABLE_NAME 
WHERE  (ta.is_ms_shipped = 0) AND (pa.index_id IN (1, 0)) AND (INFORMATION_SCHEMA.COLUMNS.COLUMN_NAME = N'T1Id') AND 
         (ta.name <> N'Table4') 
GROUP BY sc.name, ta.name 
HAVING  (SUM(pa.rows) > 0) 
ORDER BY RowCnt DESC 

上面的SQL给我造成

TableName RowCnt 
XCV   5 
ASD   5 
GHJ   2 

,但我只想得到XCV(Table1和T1Id = 1)记录计数。 如何使用上述查询或任何其他建议来做到这一点?

预期结果

Name RCount 
XCV  5 

编辑:

我有我的数据库了200多个表和它所有的表T1Id, 我的目标是找到T1Id = 1的所有表中的计数我不想在结果中包含表4。

+0

你想获得一个与最大记录?这就是为什么你的例子中预期的结果是XCV?或者你总是希望XCV成为结果? – ehh

+0

为什么'顶部(100)%'?它完全没有意义......也许你想要'顶级1'?你的问题不是很清楚。请尝试更好地描述你的目标。 –

+0

我只想从所有表的T1Id记录,不包括表4 –

回答

1

似乎要“一般”找到与1(除Table4值命名为T1Id任何表列中的所有值,我想你会想排除Table1行数为好,因为这似乎成为列值名映射的“主”参考表)。

AFAIK你将需要诉诸动态Sql为了应用过滤器。

不幸your sample query是一种误导 - 查询实际返回

Table2 6 
Table3 6 
Table1 3 

哪些是从sys.partitions.rows获得的表的整体rowcounts(即不在过滤反正)。

我认为所需的方法是在找到包含感兴趣列的'合格'表后,您需要做的是实际查询每个表格,然后用您所需的谓词(即T1ID = '1')筛选每个表格。然后你需要总结所有这些结果来预测你的最终结果。

我的解决方案太可怕了,不能在这里发帖,但我已经把Fiddle here和它的Gist Here。基本上,它会生成以下动态SQL:

WITH summedCte AS 
( 
    SELECT T1ID, COUNT(*) AS RowInTable FROM [dbo].[Table2] GROUP BY T1ID 
    UNION ALL 
    SELECT T1ID, COUNT(*) AS RowInTable FROM [dbo].[Table3] GROUP BY T1ID 
) 
SELECT T.Name, t.T1Id, SUM(c.RowInTable) AS RowsInAllTables 
    FROM summedCte c 
    INNER JOIN Table1 t 
     on c.T1Id = t.T1Id 
    WHERE t.Name = 'XCV' 
    GROUP BY t.Name, t.T1Id; 

,你可以很明显的裁缝,以满足您的需求谓词。

编辑 - 买者

看到OP的评论,即该设计用途是执行后一个“不得删除,如果在父行中使用”应用程序中的业务规则,很显然,使用游标和循环不适合生产。

的首选方法应该是沿着一个ORM或其他生产力工具的线:

  • 使用动态sql劈来构建基于CTE查询(即,而不是sp_executesql @sql,只需打印@sql并抓住所得SQL)
  • 然后可以将生成的CTE(约为200个表的UNION)烘焙到您的应用程序中以执行业务规则。然而,每当任何相关数据库DDL改变时,CTE将需要被再生并重新吸收到应用中,例如,可以避免构建通过将CTE查询保留为标记脚本。
+0

请参阅编辑...您的答案将仅查找来自table1的计数 –

+0

确认 - 一旦您找到所有带有名为T1ID的列的表格(表格4除外),然后您想要应用总计的所有计数选项所有这些表中的行按'T1ID'分组,并且返回到'T1ID',以便您可以应用'Table1.Name'? – StuartLC

+0

我的查询已满足我的要求,我的目标是显示具有T1Id计数的数据库的表名。在我qurey中显示,但我只是想在查询中添加列值条件。如T1Id = 1或2或3 ...等等。 –

相关问题