2015-07-21 83 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 ...等等。 –

相關問題