情況:具有多個可安裝模塊的PHP應用程序在數據庫中爲每個模塊創建一個新表格,格式爲mod_A,mod_B,mod_C等。每個表格都有section_id。如何查詢特定鍵值對的多個SQL表?
現在,我正在尋找特定section_id的所有條目,並且我希望除了「從mod_a,mod_b,mod_c ... mod_xyzzy其中section_id = value ...或更糟,爲每個模塊使用一個單獨的查詢。
情況:具有多個可安裝模塊的PHP應用程序在數據庫中爲每個模塊創建一個新表格,格式爲mod_A,mod_B,mod_C等。每個表格都有section_id。如何查詢特定鍵值對的多個SQL表?
現在,我正在尋找特定section_id的所有條目,並且我希望除了「從mod_a,mod_b,mod_c ... mod_xyzzy其中section_id = value ...或更糟,爲每個模塊使用一個單獨的查詢。
如果表格隨時間變化,你可以在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 '
那麼呢?
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
我打算建議和borjab一樣的想法。唯一的問題是,如果添加另一個表,則必須更新所有這些查詢。我看到的唯一的其他選項是存儲過程。
我確實想到了另一種選擇,或者至少有一種更簡單的方式來表達這一點。您也可以使用這些多個表的視圖使它們顯示爲一個,然後您的查詢看起來更清晰,更易於理解,並且當您想對這些查詢執行其他查詢時,您不必重寫長聯合查詢多個表。
也許一些額外的信息會有所幫助,但它聽起來像你已經有解決方案。您將不得不使用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>
您也可以將其封裝爲視圖。 此外請注意字段列表,而不是*,如果您打算實際使用*,我會推薦它。
那麼,只有很多方法來聚合多個表中的信息。您可以像您在示例中提到的那樣加入,也可以運行多個查詢並將它們聯合在一起,就像borjab的答案中一樣。我不知道創建與所有模塊表相交的表的一些想法對您是否有用,但是如果section_id在像這樣的表上,您將能夠從單個查詢中獲取所有內容。否則,我讚揚你的懶惰,但不敢說,我看不出有什麼辦法可以讓這份工作變得更加簡單:)
我有兩個建議。
也許你需要整合你所有的表格。如果它們都包含相同的結構,那麼爲什麼不有一個「主」模塊表,它只是添加了一個標識模塊的新列(「A」,「B」,「C」,....)
如果您的模塊表大多相同,但您有幾列不同,您仍可以將所有常用信息合併到一個表中,並保留具有這些差異的較小模塊特定表。那麼你只需要對他們進行加入。
此建議假設您提到的列section_id上的查詢對於快速查找而言非常關鍵。通過一個查詢,您可以獲得所有常用信息,如果需要,您可以在第二時間獲得任何特定信息。 (你可能不會 - 例如,如果你想驗證該部分的existense,那麼在普通表中找到它就足夠了)
或者,您可以添加另一個表,將section_id映射到模塊他們在。
section_id | module -----------+------- 1 | A 2 | B 3 | A ... | ...
這也意味着,雖然你必須運行兩個查詢,一個針對該映射表,另一對模塊表拔出任何有用的數據。
如果您需要查找所有模塊通用的其他列,可以使用這些列上的其他列和索引來擴展此表。
這種方法有一定的缺點,數據是重複的。
它是有點超出了問題的範圍,但我確實喜歡將通用模塊數據合併到一個表中。 – Esa 2008-09-29 11:14:02
SELECT * FROM (
SELECT * FROM table1
UNION ALL
SELECT * FROM table2
UNION ALL
SELECT * FROM table3
) subQry
WHERE field=value
在「從表10 ...從表100 ...從表NI ...」中失敗。 我的意思是,沒有那麼多的模塊,(大約只有60左右),但仍然... – Esa 2008-09-29 11:19:59
從數據庫側的選擇是創建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;
一個人應該小心這樣的意見,根據風味,他們可能會遇到一些性能瓶頸,如果對其應用任何形式的條件。我很確定地知道,在這樣的視圖上使用`WHERE`子句將無法使用任何基礎表的索引,並且會導致創建臨時表。此外...帽子。 – 2015-12-17 23:11:36
優秀。模塊表使用mod_A_settings的命名模式。因此,如果在一個有16頁的網站上,有50個模塊實例(比如模塊foostatistics,具有不同的配置值),mod_foostatistics_settings上會有50行,並且行指向特定的section_id:s – Esa 2008-09-29 11:17:10