0

I'm having a question about this SQL query:

 SELECT class
 FROM Ships
 WHERE name IN (SELECT ship
                FROM Outcomes
                WHERE result = ’sunk’);

Can I write in the subquery SELECT * From Outcomes or do I always need to select a row?

And what query has the best performance then?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
user1007522
  • 7,858
  • 17
  • 69
  • 113

6 Answers6

2

For performance point of view use this query

 select class 
 FROM Ships 
 join outcomes on ships.name=outcomes.ship
 and result like 'sunk'
Asif
  • 2,657
  • 19
  • 25
1

You can't put * in this subquery. The best way to do it is:

SELECT class
  FROM Ships s
 WHERE exists
     (
        select 1 
          from Outcomes o
        where s.name = o.ship
          and result = ’sunk’
       )
Robert
  • 25,425
  • 8
  • 67
  • 81
0

In this case, you need to state the column you are selecting.

I would recommend a join instead

 seLECT class 
 FROM Ships 
     inner join outcomes
     on ships.name=outcomes.ship
    WHERE result = ’sunk’
podiluska
  • 50,950
  • 7
  • 98
  • 104
0

You would need to select a single column, as you have done in your SQL example.

Its also worth noting that wildcard * is bad for performance as the server will then need to do some extra work to work out what all the columns are, as you have not explicitly stated.

If you want to include more than one column to be compared in the IN then I would suggest using a UNION in your sub-query:

SELECT class
     FROM Ships
     WHERE name IN
       (SELECT ship
        FROM Outcomes
        WHERE result = ’sunk’
        UNION
        SELECT secondColumn
        FROM Outcomes
        WHERE result = ’sunk’        
        );
Curtis
  • 101,612
  • 66
  • 270
  • 352
0

You are using In, so you need only one row to compare it to name. In this particular case, you can use a Join as an alternative. In MySQL are equally performant, but in SQL-Server In is more performant than Join. So, you you will have to return only one row in this case.

In case you use a subquery in a inner join, you could use *, but for readability is better to return the fields you will use. This example, will be

select (fields..)
from yourTable
inner join (select fields from yourTable2) T2 on ConditionOfJoining

select (fields..)
from yourTable
inner join (select * from yourTable2) T2 on ConditionOfJoining
Gonzalo.-
  • 12,512
  • 5
  • 50
  • 82
0

You should always try to avoid to use *. Even better would be never to use the *.

But in your query you MUST state the column.

  • I agree with Asif below select class FROM Ships join outcomes on ships.name=outcomes.ship and result like 'sunk' But your database design might even be better when you have a foreign key in your "outcomes" table that is linked to the id of your "ships" table, instead of using the name. (Uses less storage, and prevents typos) SELECT class FROM Ships INNER JOIN outcomes ON ships.Id = outcomes.shipId and result = ’sunk’ – KouryouChairudo Aug 23 '12 at 12:26