Question

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?

Was it helpful?

Solution

What are the most common SQL anti-patterns?

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).

OTHER TIPS

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

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.

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.

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.

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top