views:

91

answers:

7

Consider this query:

SELECT table1.id, 
       table1.review, 
       table1.time, 
       table2.author, 
       table2.title 
FROM 
table1, table2 
WHERE table1.id = table2.id 
AND table1.reviewer = '{$username}'
ORDER BY table1.id

I'm using the above quite a lot around my site's code. I find that adding the table prefixes etc. before the column names can make the query very long and take up quite a lot of lines.

Is there a way to make the above query simpler/easier?

A: 

You query looks pretty optimal aside from the potential risks with your "{$username}" portion. I could very easily see some SQL injection issues if the overall query is being rendered as a straight string and not via an abstract layer of some sort.

Inkspeak
$username is already sanitized via validation then ran through mysql_real_escape_string
Newbtophp
Excellent. That's good to hear.
Inkspeak
+1  A: 

You can use table aliases

SELECT t1.id, t1.review, t1.time, t2.author, t2.title 
FROM 
table1 AS t1, table2 AS t2
WHERE t1.id = t2.id AND t1.reviewer = '{$username}'
ORDER BY t1.id
Fanis
+5  A: 

First of all, you may want to give shorter aliases to your tables. In addition, you are using the implicit join syntax which complicates the WHERE clause, and is not recommended in general. You may want to use the more modern explicit syntax instead:

SELECT    t1.id, t1.review, t1.time, t2.author, t2.title 
FROM      table1 AS t1
JOIN      table2 AS t2 ON (t2.id = t1.id)
WHERE     t1.reviewer = '{$username}'
ORDER BY  t1.id

Note that JOIN is a synonym for INNER JOIN, and the AS keyword is optional when defining table aliases. You can simply use ... FROM table1 t1 ... instead of ... FROM table1 AS t1 ....

Daniel Vassallo
The OP posted ANSI-89 syntax; yours is ANSI-92. But there's no performance difference.
OMG Ponies
Agreed. No performance difference, but simplifies the `WHERE` clause.
Daniel Vassallo
I'd agree with enhancing all queries for all to use 92 over 89.
p.campbell
A: 

The format I find most readable is:

SELECT 
   t1.id, 
   t1.review, 
   t1.time, 
   t2.author, 
   t2.title 
FROM 
   table1 t1

   JOIN table2 t2
      on ( t2.id = t1.id )

WHERE 
   t1.reviewer = '{$username}'

ORDER BY 
   t1.id
Ron Savage
Each to their own, I suppose: 3 too many blank lines, and far too many things spread over multiple lines where one is sufficient for my taste (at least four more lines that would not appear in my SQL). I assume the 'on' instead of 'ON' is a typo? And I'd use the explicit AS keyword to designate the table aliases. AFAIAC, the query shown looks bigger and more complex than the simple query it actually is - and the difference is the layout.
Jonathan Leffler
It's less obvious with a small query like this but when you get up to 60+ fields across 10+ tables with more complex JOIN clauses and multiple conditions the extra white space really helps to make it look less intimidating and more readable.
Ron Savage
+1  A: 

Why dont you make a function , pass the table name and other parameter and return either values or sql query.

Your query is already simplified, i think you are worried about doing this multiple times. so better will be to create a small function in that case.

I had similar problem, which i got rid using function.

JapanPro
An example would be great :)
Newbtophp
+1 just for the idea of refactoring. Copy/pasting code all over the place is just gauche.
p.campbell
Passing the table name as a variable ensures using dynamic SQL.
OMG Ponies
A: 

It's not clear if you're "using the above code all over the site" verbatim, or the style of SQL without aliases.

If this specific piece of code is being copy/pasted, consider encapsulating this logic in a function in your PHP modules.

function GetReviewerTitles($reviewer)
{
    //your select statement.
    $reviewerSQL = sprintf("SELECT t1.id,  t1.review, t1.time, t2.author, t2.title FROM  table1 as t1 INNER JOIN table2 AS t2 ON t1.id=t2.id WHERE t1.reviewer = '%s' ORDER BY t1.id",
                   mysql_real_escape_string({$username}));

    // Perform Query
    $result = mysql_query($reviewerSQL);

    //return if/when necessary
}
p.campbell
I'm using the style of SQL without aliases around the site, also note; $username can't be parsed within single quotes (within the mysql_real_escape_string function call)
Newbtophp
A: 

I suggest using a view:

CREATE VIEW ReviewInfo(id, review, time, author, title, reviewer) AS
    SELECT t1.id,     t1.review, t1.time, 
           t2.author, t2.title,  t1.reviewer
      FROM table1 AS t1 JOIN table2 AS t2 ON t1.id = t2.id 

Now you can write your query as:

SELECT id, review, time, author, title
  FROM ReviewInfo
 WHERE reviewer = '{$username}'
 ORDER BY id;

Note the use of abbreviations for the table names in the view definition - that is a technique you could use in your query even if you don't use a view. And the notation using an explicit JOIN operator in the FROM clause with the ON condition is preferred to the old-style FROM table1, table2.

Jonathan Leffler