来自内部联接表的“SELECT *”

时间:2009-05-18 14:07:24

标签: sql sql-server inner-join

如何选择两个连接表的所有字段,而不与公共字段冲突?

假设我有两个表,ProductsServices。我想做一个这样的查询:

SELECT Products.*, Services.* 
FROM Products 
INNER JOIN Services ON Products.IdService = Services.IdService

此查询的问题是IdService会出现两次并导致一系列问题。

到目前为止,我发现的另一种方法是区分ProductsIdService之外的所有字段。但是这样我每次向Products添加新字段时都必须更新查询。

有更好的方法吗?

8 个答案:

答案 0 :(得分:13)

你不应该在生产代码中使用SELECT *(好吧,几乎从来没有,但是可以很容易地计算出合理的时间)。

答案 1 :(得分:12)

What are the most common SQL anti-patterns?

你已经击中反模式#1。

更好的方法是提供一个字段列表。获得快速字段列表的一种方法是

sp_help tablename

如果你想从这个查询创建一个视图 - 使用select *会让你更麻烦。 SQL Server在创建视图时捕获列列表。如果您编辑基础表并且不重新创建视图 - 您注册时遇到了麻烦(我有这种性质的生产火灾 - 虽然视图是针对不同数据库中的表)。

答案 2 :(得分:3)

据我所知,你必须避免SELECT *,但这不是一个问题。

SELECT *通常被认为是一个等待发生的问题,因为你引用它作为一个优势!通常,在修改数据库时出现查询的额外结果列会导致问题。

答案 3 :(得分:1)

您的SQL方言是否支持COMPOSE? COMPOSE删除了在等值连接上使用的列的额外副本,如示例中的那个。

答案 4 :(得分:1)

正如其他人所说,Select *是个坏消息,特别是如果将其他字段添加到您要查询的表中。您应该从表中选择所需的确切字段,并且可以对具有相同名称的字段使用别名,或者只使用table.columnName。

答案 5 :(得分:1)

不要使用*。使用这样的东西:

SELECT P.field1 AS 'Field from P'
     , P.field2
     , S.field1 AS 'Field from S'
     , S.field4 
  FROM Products P
       INNER JOIN 
       Services S
       ON P.IdService = S.IdService

答案 6 :(得分:0)

这是正确的,列出您想要的字段(在SQL Server中,您可以将它们从对象浏览器中拖出,因此您不必全部键入它们)。顺便提一下,如果您的特定查询不需要字段,请不要列出它们。这会为服务器创建额外的工作并耗尽额外的网络资源,并且可能是在整个系统中完成这些浪费的查询每天运行数千次时导致性能低下的原因之一。

至于它是一个维护问题,只需要在使用您的查询的应用程序部分受其影响时添加字段。如果您不知道新字段会有什么影响或者您需要添加它的位置,则不应添加该字段。通过使用select *意外地添加新文件也会导致维护问题。创建性能问题以避免进行维护(您可能根本不需要进行维护,因为列更改应该很少(如果它们不是您需要查看您的设计))是非常短视的。

答案 7 :(得分:0)

最好的方法是从查询中指定所需的确切字段。无论如何,你不应该使用*

使用*来获取所有字段很方便,但它不会生成健壮的代码。表中的任何更改都将更改从查询返回的结果,但这并不总是可取的。

您应该只返回您真正想要的查询数据,并按照您想要的确切顺序指定。这样,即使您向表中添加字段或更改表中字段的顺序,结果也会完全相同。

指定确切的输出是更多的工作,但从长远来看,它通常会得到回报。当你进行更改时,只有实际更改的内容会受到影响,您不会获得级联效果,这会破坏您甚至不知道的代码会受到影响。