2011-02-23 140 views
3

我最近被分配了創建拍賣系統的任務。在我的工作中,我遇到過很多場合,包含連接的SQL查詢由於列名不明確而無法執行。考慮這個(簡化的)表結構的拍賣:如何避免列名衝突?

auction

  • id
  • name
  • uid

表(創建該拍賣的用戶的ID) item

  • id
  • name
  • uid
  • aid
  • price(初始價格)(其中項目是可用的拍賣的ID)
(所添加的項目的用戶的ID)

user

  • id
  • name

bid

  • id
  • uid
  • iid(項,它的價格已經提出)(即放置在出價的用戶的ID)
  • price(所報的價格)

正如你所看到的,有一些有衝突的名稱很多列。加入這些表格需要採取一些措施來消除歧義。

我可以想出兩種方法來做到這一點。首先是對列進行重命名,並在其前面添加縮寫表名稱,以便拍賣ID將變爲a_id,商品ID將變爲i_id,並且bid表中的商品ID將變爲b_i_id。這非常穩固,但降低了列名的可讀性。

另一種方式我能想到的是寫明確的查詢:

SELECT `bid`.`id`, `user`.`name`, `bid`.`price` 
FROM `bid` 
JOIN `item` ON `item`.`id` = `bid`.`iid` 
JOIN `user` ON `user`.`id` = `bid`.`uid` 
JOIN `auction` ON `auction`.`id` = `item`.`aid` 
WHERE `bid`.`price` > `item`.`price` 
AND `auction`.`id` = 1 
GROUP BY `user`.`id` 
ORDER BY `bid`.`price` DESC; 

這是可讀的和明確的,但需要大量額外的按鍵。

我使用第二種方法,但也許有其他人,你已經成功地用於類似的情況?你如何避免SQL查詢中的列名衝突?

+12

如果'keystrokes'是當你程序,你需要重新考慮你的職業生涯路徑的關注! – RichardTheKiwi 2011-02-23 11:57:46

+1

@Richard:好的,你讓我用這個,這句話值得+1 :) – mingos 2011-02-23 12:10:32

+1

放下反引號',這些與SQL無關(檢查標準!)並保存一些擊鍵。 – 2011-02-23 14:19:58

回答

3

我的經驗是,該額外的按鍵遠遠超過它需要通過從長遠來看,遠鍵入這些時間短的優勢,在最新的,當你需要看一個查詢,你已經寫了一一年前左右。

12

可能你可以嘗試在表名上使用aliases

select * from table1 as T1 
join table2 as t2 on (t1.key=t2.foreignkey) 
+0

這就是我所做的,但是在多次嵌套連接之後,我仍然有同樣的痛點。 – Dave 2013-11-08 19:22:58

5

You need to use AS alias.

您可以通過使用別名給表或列的另一個名字。如果您有很長或複雜的表名或列名,這可能是一件好事。

別名可以是任何東西,但通常很短。

+0

您不需要'AS'來使用別名。 – 2011-02-23 14:20:54

+3

@Frank Heikens:我知道但是使用這個關鍵詞是好的做法:) – Sarfraz 2011-02-23 17:43:48

4

你的做法是正確的,但你也可以爲你的表的別名:

SELECT a.* FROM TableA A 
在這裏

你可以參考表A的簡單A.

2

拇指的黃金法則是,如果您將永遠使用多個表,別名表以及顯式別名所有列。

這種一致性會讓你深入到年輕的padawan中。

2

更改您的命名約定,以便每個數據元素在架構中具有唯一的名稱,例如auction_idbid_id,user_id等。理想情況下,數據元素的名稱不會在表格之間變化,但有時您需要添加限定符以創建同義詞,例如adding_user_idbidding_user_id如果user_id在同一個表中出現兩次。您應該在數據字典中記錄數據元素名稱及其同義詞。

+0

同意,但是在大多數人陷入這種困境時,他們已經深入到一個沒有這種文檔的系統中,這意味着花費數週的時間修復別人創建的問題=( – Dave 2013-11-08 19:25:46

0

您也可以定義表列的表名稱旁邊:

SELECT P.*,T.name AS type FROM <TABLE-A> AS P LEFT JOIN <TABLE-B> AS T ON P.id=T.id