First and foremost, get a thorough understanding of joins. Not just inner and left joins either. Know what a cross join does and a full outer join. Know the circumstances that would cause you to choose a particular type of join. Understand that they are not interchangeable and that query that uses a left join may return different results than one that uses an inner join. (One would think that would be obvious but I've read too many questions where people in decribing their problem, somewhat randomly try different joins.)
Next really understand aggregates and how they work. Mysql will let you get away with not doing group bys in a standard way. But have the discipline to completely define the group by clause properly. It will help you understand what you are doing and will make your knowldge more easily transferable to other databases.
Learn what the case statement does.
When doing complex queries learn to work in chunks. Verify at each chunk that you have the results you expect. So for instance suppose you need to write a reporting query on orders that have been returned in the last 3 months and the reason for the return as well as the contact information for the customer. First step is to get the orders returned in the last three months. Once you know you have that solid, you can add the information on the reason for return. Once you have that solid, you can add the customer who returned it. Once you have that solid, add the contact information for the person. At each stage, check your results and see if they make sense. In this case, I probably want to end up with only one record per returned order. If at any intermediate stage, the number of results goes up or down, you know you have a problme with the query. Sometimes in building blocks, you will want to see additional fields just to verify if the information is correct. I put these on a separate line and comment them out as I work through the next step (removing them at the end once I know I'm right) so they are available to see again easily if adding another wrinkle made the query go funny. You cannot do complex querying correctly without a thorough understanding of what your results should be look like. Thinking it looks OK becasue it returned some results will almost guarantee that you have wrong results a good portion of the time.
Here is a list of some basic things you should be able to do in SQL without having to think about it:
- First a straight up select with no joins (and no select *) but with
conditions on the select
- You should know how to combine two or more tables and get records
that are in all the tables
- You should know how to combine two or more tables and get records
that are in all the tables but return only one record from the table
with the many side of the one-to-many relationship
- You should be able to get the records in one table but not in an
associated table
- You should be able to Aggregate data for a report
- You should be able to insert one record to a table
- You should be able to update one record in a table
- You should be able to delete one record in a table
- You should be able to insert a group of records to a table without
a cursor
- You should be able to update a group of records in a table
without a cursor
- You should be able to delete a group of records in a table without
a cursor
- You should be able to perform multiple actions in one
transaction and handle error trapping
- You should be able to create union of records and know when to
use UNION vice UNION ALL
- You should be able to vary the data for one field based on some
criteria (using CASE)
Once you feel comfortable with your basic SQL knowledge, get to know your database structure. I can write complex queries against the very complicated dbs I support much faster than other people because I understand the structure and don't have to think about where things are stored. If you understand the table structure and foreign key relationships and where lookup values are stored and what the columns mean (not just their name but what data is held in them) then you can be expert in querying that database. The first thing I do in any new job is thoroughly understand the db structure.