2008-09-19 66 views
1

情況:具有多個可安裝模塊的PHP應用程序在數據庫中爲每個模塊創建一個新表格,格式爲mod_A,mod_B,mod_C等。每個表格都有section_id。如何查詢特定鍵值對的多個SQL表?

現在,我正在尋找特定section_id的所有條目,並且我希望除了「從mod_a,mod_b,mod_c ... mod_xyzzy其中section_id = value ...或更糟,爲每個模塊使用一個單獨的查詢。

回答

1

如果表格隨時間變化,你可以在SP僞碼 - 你必須填寫):

SET @sql = '' 

DECLARE CURSOR FOR 
SELECT t.[name] AS TABLE_NAME 
FROM sys.tables t 
WHERE t.[name] LIKE 'SOME_PATTERN_TO_IDENTIFY_THE_TABLES' 

- 或該

DECLARE CURSOR FOR 
SELECT t.[name] AS TABLE_NAME 
FROM TABLE_OF_TABLES_TO_SEACRH t 

START LOOP 

IF @sql <> '' SET @sql = @sql + 'UNION ALL ' 
SET @sql = 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value ' 

END LOOP 

EXEC(@sql) 

我偶爾使用該技術,當出現只是沒有做出任何明顯的方法無需動態SQL即可滿足未來需求。

注意:在你的循環,你可以使用COALESCE/NULL傳播技巧和循環之前離開該字符串爲NULL,但如果你不熟悉的成語它不是明確:

SET @sql = COALESCE(@sql + ' UNION ALL ', '') 
    + 'SELECT * FROM [' + @TABLE_NAME + '] WHERE section_id=value ' 
+0

優秀。模塊表使用mod_A_settings的命名模式。因此,如果在一個有16頁的網站上,有50個模塊實例(比如模塊foostatistics,具有不同的配置值),mod_foostatistics_settings上會有50行,並且行指向特定的section_id:s – Esa 2008-09-29 11:17:10

1

那麼呢?

SELECT * FROM mod_a WHERE section_id=value 
UNION ALL 
SELECT * FROM mod_b WHERE section_id=value 
UNION ALL 
SELECT * FROM mod_c WHERE section_id=value 
0

我打算建議和borjab一樣的想法。唯一的問題是,如果添加另一個表,則必須更新所有這些查詢。我看到的唯一的其他選項是存儲過程。

我確實想到了另一種選擇,或者至少有一種更簡單的方式來表達這一點。您也可以使用這些多個表的視圖使它們顯示爲一個,然後您的查詢看起來更清晰,更易於理解,並且當您想對這些查詢執行其他查詢時,您不必重寫長聯合查詢多個表。

0

也許一些額外的信息會有所幫助,但它聽起來像你已經有解決方案。您將不得不使用section_id從所有表中進行選擇。您可以使用連接而不是表格列表,並加入section_id。例如

select a.some_field, b.some_field.... 
from mod_a a 
inner join mod_b b on a.section_id = b.section_id 
... 
where a.section_id = <parameter> 

您也可以將其封裝爲視圖。 此外請注意字段列表,而不是*,如果您打算實際使用*,我會推薦它。

0

那麼,只有很多方法來聚合多個表中的信息。您可以像您在示例中提到的那樣加入,也可以運行多個查詢並將它們聯合在一起,就像borjab的答案中一樣。我不知道創建與所有模塊表相交的表的一些想法對您是否有用,但是如果section_id在像這樣的表上,您將能夠從單個查詢中獲取所有內容。否則,我讚揚你的懶惰,但不敢說,我看不出有什麼辦法可以讓這份工作變得更加簡單:)

1

我有兩個建議。

  1. 也許你需要整合你所有的表格。如果它們都包含相同的結構,那麼爲什麼不有一個「主」模塊表,它只是添加了一個標識模塊的新列(「A」,「B」,「C」,....)

    如果您的模塊表大多相同,但您有幾列不同,您仍可以將所有常用信息合併到一個表中,並保留具有這些差異的較小模塊特定表。那麼你只需要對他們進行加入。

    此建議假設您提到的列section_id上的查詢對於快速查找而言非常關鍵。通過一個查詢,您可以獲得所有常用信息,如果需要,您可以在第二時間獲得任何特定信息。 (你可能不會 - 例如,如果你想驗證該部分的existense,那麼在普通表中找到它就足夠了)

  2. 或者,您可以添加另一個表,將section_id映射到模塊他們在。

     
    section_id | module 
    -----------+------- 
         1 | A 
         2 | B 
         3 | A 
        ... | ... 
    

    這也意味着,雖然你必須運行兩個查詢,一個針對該映射表,另一對模塊表拔出任何有用的數據。

    如果您需要查找所有模塊通用的其他列,可以使用這些列上的其他列和索引來擴展此表。

    這種方法有一定的缺點,數據是重複的。

+0

它是有點超出了問題的範圍,但我確實喜歡將通用模塊數據合併到一個表中。 – Esa 2008-09-29 11:14:02

0
SELECT * FROM (
    SELECT * FROM table1 
    UNION ALL 
    SELECT * FROM table2 
    UNION ALL 
    SELECT * FROM table3 
) subQry 
WHERE field=value 
+0

在「從表10 ...從表100 ...從表NI ...」中失敗。 我的意思是,沒有那麼多的模塊,(大約只有60左右),但仍然... – Esa 2008-09-29 11:19:59

0

從數據庫側的選擇是創建UNION ALL的各種表中的圖。添加表格時,您需要將其添加到視圖中,否則它將看起來像一個表格。

CREATE VIEW modules AS (
    SELECT * FROM mod_A 
    UNION ALL 
    SELECT * FROM mod_B 
    UNION ALL 
    SELECT * FROM mod_C 
); 

select * from modules where section_id=value; 
+0

一個人應該小心這樣的意見,根據風味,他們可能會遇到一些性能瓶頸,如果對其應用任何形式的條件。我很確定地知道,在這樣的視圖上使用`WHERE`子句將無法使用任何基礎表的索引,並且會導致創建臨時表。此外...帽子。 – 2015-12-17 23:11:36