2012-10-31 35 views
25

我正在分析一個相當可怕的遺留數據庫/代碼庫,試圖通過將查詢合併到連接中來減少服務器負載(包括通常的電子郵件警報cron作業調用超過一百萬個單獨的查詢)。在一個連接中,如何爲所有列名前綴來自它的表

SELECT * FROM 
class_alerts_holding ah 
INNER JOIN class_listings l ON l.id = ah.lid 
INNER JOIN class_users u ON u.id = ah.uid 
LEFT JOIN class_prodimages pi ON pi.pid = ah.lid 

該吐出120列...

aid | id | lid | uid | oid | catName | searchtext | alertfreq | listType | id | owner | title | section | shortDescription | description | featured | price | display | hitcount | dateadded | expiration | url | notified | searchcount | repliedcount | pBold | pHighlighted | notes | ... 

爲了幫助我如何構建新的查詢分析,這將是真棒,如果我能在表中的結果前綴的列,他們來自JOIN例如

class_alerts_holding.aid | class_alerts_holding.id | class_listings.lid | ... 

有沒有辦法做到這一點?

+1

恐怕唯一的可能就是打字/手動生成'SELECT'語句 –

+1

您給了我一個搜索谷歌很長時間的理由。我也對過去感興趣,但是我確實沒有找到任何可行的方法來做到這一點 –

+0

[SQL select連接的可能重複:是否可以將所有列作爲前綴前綴。\ *'?] (http://stackoverflow.com/questions/329931/sql-select-join-is-it-possible-to-prefix-all-columns-as-prefix) –

回答

18

你可以

select ah.*, l.*, u.*, pi.* from ... 

則列將返回由表下令至少。

對於每兩個組之間更好的區別,你還可以添加「分隔符」欄目是這樣的:(編輯,以去除明確的別名是不必要的,見註釋)

select ah.*, ':', l.*, ':', u.*, ':', pi.* from ... 

+1

我冒昧地在您的建議中「擴展」,通過添加我在分析* my *查詢時經常做的事情。如果您認爲它在您的答案中沒有位置,請隨時回滾我的更改。 –

+1

+1分隔符絕對有幫助,並且強制排序。儘管列排序似乎已經按照JOIN(MySQL 5.5.25)的順序排列。 –

+0

@AndriyM稍微簡化查詢:我發現沒有'AS'我得到了相同的結果,例如 'select ah。*,':',l。*,':',...' –

32

誰能把查詢的字段,並給他們別名:

SELECT  ah.whateverfield1 AS 'ah_field1', 
      ah.whateverfield2 AS 'ah_field2', 
      l.whateverfield3 AS 'l.field3', 
      [....] 
FROM  class_alerts_holding ah 
INNER JOIN class_listings l ON l.id = ah.lid 
INNER JOIN class_users u ON u.id = ah.uid 
LEFT JOIN class_prodimages pi ON pi.pid = ah.lid 

其工作有點手動設置,如果你有很多領域,但你可以用這個查詢簡化這個.. 。

SHOW FULL FIELDS FROM your_table_name; 

...和一個好的文本編輯器和複製&粘貼。

+8

...並且與接受的答案不同,這實際上回答了原始問題! – nurdglaw

+7

因此,沒有辦法僅僅使用table。*作爲表並將表中的所有列作爲table.columnName返回? – James111

+0

如果您的編輯器支持正則表達式查找並替換,那麼你可以找到這個模式 - >(?)(。*?)的每個列名,並用th代替是模式 - > \ 1PREF。\ 2 AS PREF_ \ 2, – Teddy

8

動態命名列的方法是生成引用information_schema的預處理語句。這會給你你想要的結果。

SET @sql = NULL; 
SELECT CONCAT(
    'SELECT ',GROUP_CONCAT(c.TABLE_NAME,'.',c.COLUMN_NAME,' AS `',c.TABLE_NAME,'.',c.COLUMN_NAME,'`'),' 
    FROM class_alerts_holding 
    INNER JOIN class_listings ON class_listings.id = class_alerts_holding.lid 
    INNER JOIN class_users ON class_users.id = class_alerts_holding.uid 
    LEFT JOIN class_prodimages ON class_prodimages.pid = class_alerts_holding.lid' 
) 
INTO @sql 
FROM INFORMATION_SCHEMA.COLUMNS c 
WHERE c.TABLE_NAME IN ('class_alerts_holding','class_listings', 
         'class_users','class_prodimages');  
PREPARE sql_statement FROM @sql; 
EXECUTE sql_statement; 

的GROUP_CONCAT()函數爲1024個字符的默認限制,所以取決於列在表中的數字,您可能需要以產生準備好的語句,以提高這一限制。

SET SESSION group_concat_max_len = 1000000; 

如果需要,此命令將提高組連接限制。 -

+1

你能舉一個這個輸出的例子嗎? –

+1

當然,這裏是這個例子的小提琴,http://sqlfiddle.com/#!9/e99bf2/10。把它放在一起看到你需要拿出表別名,幷包括AS語句,所以我編輯,以包括這些。小提琴似乎很奇怪它如何顯示列名。例如,它僅顯示第一列的id。但在任何其他客戶端中,您將看到指定的'class_alerts_holding.id'。 –

+0

對不起,在幾天前瀏覽頁面時發生了肯定的事情:( →直到答案正在編輯中才能更改該投票 –

2

基於由koljaTM和AndriyM提出的解決方案,也許一個更好的解決辦法是寫你的查詢是這樣的:

select 
    '--TABLE_AAA:--', TABLE_AAA.*, 
    '--TABLE_BBB:--', TABLE_BBB.*, 
    '--TABLE_CCC:--', TABLE_CCC.*, 
    '--TABLE_DDD:--', TABLE_DDD.* 
from ... 

不幸的是這仍然不是在案件不夠好時,一個(或多個)的表格包含的列名稱可能超出屏幕寬度。(所以你可能會在屏幕上看到20列,但屏幕上仍然不會顯示它們來自哪張表的名稱。)

如果SQL提供了一種自動爲列名添加前綴的方法與表名...

+2

re:屏幕寬度-PostgreSQL和MySQL shell有一個垂直結果模式,其中每個值被打印爲一列:值對Postgres:在shell中鍵入'\ x'以切換到擴展模式。MySql:以'\ G'結束查詢,而不是';'。 –

+0

「如果SQL提供了一種自動爲列名自動加上表名」+1 – Teddy

0

@奧爾登-W,您可以添加TABLE_SCHEMA條件的地方要不要從不同的架構

混淆了相同的表名
WHERE c.TABLE_SCHEMA='YOUR_SCHEMA_NAME' AND c.TABLE_NAME IN (....) 
相關問題