2011-02-23 135 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