views:

217

answers:

8

How do you select all fields of two joined tables, without having conflicts with the common field?

Suppose I have two tables, Products and Services. I would like to make a query like this:

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

The problem with this query is that IdService will appear twice and lead to a bunch of problems.

The alternative I found so far is to discriminate every field from Products except the IdService one. But this way I'll have to update the query every time I add a new field to Products.

Is there a better way to do this?

+13  A: 

You should NEVER have SELECT * in production code (well, almost never, but the times where it is justified can be easily counted).

erikkallen
What if I wanted to create a view from this query?
djeidot
That's still a bad idea. Depending on your RDBMS, either the view won't update it's own field list until you've recompiled it anyway, so you gain nothing, or it will in which case you have the same problem that you have with tables - a change to an underlying table could suddenly break an application.
Tom H.
One of the cases where it's justified (and I'm sure you can't count those) is a subquery after an exists clause. Like "where id not in (select * from table where linkid = id")
Andomar
@Adnomar. Yes, but there you are not really doing a "select *", it's just that SQL has no better way to express a semi join.
erikkallen
+1  A: 

Does your dialect of SQL support COMPOSE? COMPOSE gets rid of the extra copy of the column that's used on an equijoin, like the one in your example.

Walter Mitty
+3  A: 

As far as I am aware you'll have to avoid SELECT * but this't really a problem.

SELECT * is usually regarded as a problem waiting to happen for the reason you quote as an advantage! Usually extra results columns appearing for queries when the database has been modified will cause problems.

Dave Webb
+12  A: 

http://stackoverflow.com/questions/346659/what-are-the-most-common-sql-anti-patterns/346679#346679

You've hit anti-pattern #1.

The better way is to provide a fieldlist. One way to get a quick field list is to

sp_help tablename

And if you want to create a view from this query - using select * gets you in more trouble. SQL Server captures the column list at the time the view is created. If you edit the underlying tables and don't recreate the view - you're signing up for trouble (I had a production fire of this nature - view was against tables in a different database though).

David B
+1  A: 

As others have said the Select * is bad news especially if other fields are added to the tables in which you are querying. You should select out the exact fields you want from the tables and can use an alias for fields with the same names or just use table.columnName.

CSharpAtl
A: 

That would be correct, list the fields you want (in SQL Server you can drag them over from the object browser, so you don't have to type them all). Incidentally, if there are fields your specific query doe not need, do not list them. This creates extra work for the server and uses up extra network resources and can be one of the causes of poor performance when it is done thoughout your system and such wasteful queries are run thousands of times a day.

As to it being a maintenance problem, you only need to add the fields if the part of the application that uses your query would be affected by them. If you don't know what affect the new field would have or where you need to add it, you shouldn't be adding the field. Also adding new fileds unexopectedly through the use of select * can cause maintenance problems as well. Creating performance problems to avoid doing maintenance (maintenance you may never even need to do as column changes should be rare (if they aren't you need to look at your design)) is pretty short-sighted.

HLGEM
A: 

The best way is to specify the exact fields that you want from the query. You shouldn't use * anyway.

It is convenient to use * to get all fields, but it doesn't produce robust code. Any change in the table will change the result that is returned from the query, and that is not always desirable.

You should return only the data that you really want from the query, specified in the exact order you want it. That way the result looks exactly the same even if you add fields to the table or change the order of the fields in the table.

It's a litte more work to specify the exact output, but in the long run it usually pays off. When you make a change, only what you actually change is affected, you don't get cascading effects that breaks code that you didn't even know was affected.

Guffa
+1  A: 

Do not use *. Use somthing like this:

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
Dmitri Kouminov