SQL is hard. Who’s to say whether it’s harder for the person that has no technical background or the one that is comfortable with object oriented, procedural, or functional styles and has to cross the great divide to set-based, declarative queries. In either case, there’s a journey ahead of you.
Luckily there are a lot of great resources out there to help. From live webcasts like SQLLunch and 24 hours of PASS, to local SQL Saturday events, from recorded TechEd sessions to hundreds of books to blogs posts on sites like this….the list goes on.
But it’s still a long road, and building that initial solid foundation can be a hard step.
The Inquisitive Coworker
Over the years I’ve never had a good answer to the “where can I go to learn more about that” question from coworkers. There’s a ton of beginner books out there, but who has the time to weed through them and figure out which ones are more dangerous than they are helpful?
So the thought runs through my head, “How _did_ I learn that CROSS JOIN trick I just used?” and of course I don’t remember. Except I’m willing to bet that I learned it while trying to solve a problem. It might have been from a book, from a video, from trying someone else’s answer to one of Denis’s SQL puzzles. The driver was the fact that I had a problem to solve and that new tool I picked up was what helped me solve it. And I later remembered it, used it again, and learned more about it because it helped me solve a problem.
Learn by Doing
I’ve always liked the idea behind the TryRuby site, an interactive experience that walks you through the basics of Ruby as you type them into an interactive console. Short of finding a mentor for every person that wants to give Ruby a try, this seems like an excellent way to provide a guided experience and help you build that initial foundation.
Why not do this with SQL?
And why not take it even further? After all, if you have an interactive site that helps build some basic skills with SQL, why can’t it also offer a section for more advanced techniques? Sure, you can download a free version of SQL Server Express or one of the other brands of SQL and try to learn these things on your own, but a guided set of exercises on a topic might be the perfect foundation before trying to branch out and try to invent your own problems to solve.
And thus was born the idea of SQLisHard.com.

It’s Still Early
It’s still in the very early stages with only a single set of exercises, and I’ve only implemented about half of that set. There’s a longer wishlist of features on a Trello board, but the initial focus here was making the core experience work. It’s not as whimsical as the TryRuby site (Damnit Jim, I’m a software engineer not a web designer). Most of the fanciest features are focused on helping me choose the right improvements to make; easy deployment, anonymous usage statistics, error capturing and reporting, and so on.
My list of “features I haven’t gotten to yet” starts with “finish the first exercise set”. After that I have more exercise sets, both foundational and “where can I go to learn that” advanced sets, an ability to save your progress (register/login) while continuing to let people without pre-registering (or without registering at all, up front registration annoys me), more permanent pieces for the few that I took shortcuts on, alternative exercise goals so you can try several queries while learning a single step, performance improvements and retry logic
But most importantly, I’m looking for feedback. Does this seem like something you would point a beginner to? When your coworker asks where they could learn to use windowing functions, could you imagine a method like this being useful?
Check it out: SQLisHard.com
The technologies behind both the site and the deployment process were interesting, I’ll have follow-up posts on those soon as well.
40 Comments
I like this. It feels quite a bit like the stuff at CodeAcademy.
This is a great idea Eli
Great idea, couldn’t get it to display on my phone, but will try next time on a better form factor
Love this. I am always looking for more ways to learn SQL and I find the best is to just jump in and do it. I believe you learn better by doing. Just two things I would suggest:
1. Allow for the user to log in to track progress. This will of course be something that can be added later after you have more content.
2. If the user gets something wrong, maybe give them a hint as to where they went wrong. Once you get to more complex queries, it may be harder for the user to learn if they are not guided in the right direction.
Thanks for the positive feedback everyone 🙂
Ross: I didn’t build it with a responsive layout, though it is on my “maybe later” list. My assumption is that there wouldn’t be many people with the patience to type out queries in a tablet or phone factor with on-screen keyboards, but I’m willing to be proven wrong 🙂
Stanley: Yep, behind the scenes it already allocates an account once you start, with the idea that when I add registration/login capability later it would merge any anonymous progress you have with the new/existing account. On #2, I’m still trying to think about how to do this well. Really the big gap between a real mentor and a system like this is that feedback loop, but I haven’t worked out yet how to make the system flexibly guess where you went wrong to offer good advice. Great feedback, thanks 🙂
Great idea, great execution!
I like it! I actually just started my new programming job (programming background, little SQL background) and really enjoyed going through these. I’ve got some feedback for you:
On s2.2, it might be helpful to change the ‘2013-01-01’ to something like ‘2013-01-30’ so we know whether we’re using “the queens english” or “american english” standards in dates.
I also have a question… I’m confused as to why on S4.0, this was accepted:
SELECT *
from Customers
INNER JOIN Orders ON CustomerId = Customers.Id
While this was not:
SELECT *
from Orders
INNER JOIN Customers ON CustomerId = Customers.Id
Anyway, I’m loving this learning resource and looking forward to continuing to use it as you build it further.
Thanks for putting it out there!
sql is not hard
if you think it is you’re just retarded
Great idea for beginners.
A great idea and the start you’ve made is well executed.
I look forward to seeing it develop more – and then learning more SQL from it, myself!
A really worthwhile project!
Thanks
It’s not that hard…
One has to master 1 command …the SELECT, the other 3 are trivial along with the rest of the syntax.
first learn SELECT…WHERE , then how to JOIN, then GROUP BY and then OVER and maybe some kinky advanced stuff.
Overall it can all be learned in a day i’d say.
Then it comes the database management and administration which is another stuff, but if you do not design or administrate dbs, just knowing SQL to work with data is not all that hard imo.
So far, two people that left comments without reading the post.
JJ, Chris H, Elias: Thanks, it’s comments liek that that will give me the energy to open this up on work on it on a Saturday morning 🙂
Earlier Chris: Good idea, that format for dates is how I write them by default now, so I didn’t even recognize the potential for confusion, I like the solution of using the 30th. On the other exercise, I’ve seen a couple people have similar issues with order by statements I wasn’t expecting. Currently I verify records with the assumption that they are going to be in the order I get when executing the solution statement, but maybe i can add an order-less comparison. You would still be able to get a false positive success if you managed to do an incorrect query that returned the right number of records and the 1st 100 were in the answer key, but that seems like i would be hard to do accidentally.
“no” and “lol”: There is a lot more to SQL than just a few commands, being able to use CROSS and LEFT joins well can significantly simplify a lot of logic, windowing functions like ROW_NUMBER can collapse statements that used to require a lot more work (or application processing), query tuning (which I hope to get to at some point) is not at all simple or something you would learn in a day. After learning some basics it is easy to fall for the trap that we know everything there is to know about a subject, hopefully you’ll come back in the future and be open to trying some of the more advanced exercises (provided, of course, that I actually get to those :P).
Nice job! I could definitely see this being useful.
One thing that might be nice is a sign-up form for people who want to know when you get a chance to add more content.
(it’s not “along road,” it’s “a *long* road.”) 😉
This is a great idea that I would definitely point cow-orkers to. If this expands with more complex examples it would be great for everyone. Is there a chance that we could submit lessons or does the method to create the examples not allow for easy submission?
[no need to publish this comment.]
excellent. i would point people there.
couple design things:
– “let’s get started” on home page MUST be bigger and more obvious. giant button.
– remove some gray-space between exercise and query designer and/or make designer a tiny bit shorter.
– move the “excellent, let’s continue” result to the top of the designer. it might wreck my previous comment about saving space, but because i had scrolled down a bit to see the entire designer, i didn’t see “let’s continue” come up when i finished the exercise.
– possibly add some css to the ‘execute’ btn. i didn’t see it at first. no biggie.
> i think i have a pretty average-sized monitor and i have to scroll about 1 inch to see everything; annoying to have to constantly scroll a tiny distance just to be sure i’m not missing something at the top or bottom. just a few tweaks here and there (slightly narrower left column could help) and scrolling would be gone. (i know there will prob be scrolling sometimes for longer exercises, etc.. i would keep the designer visible at all times.)
I love this idea, thank you! Keep it up!
I used to use a lot of SQL in Visual Basic. What I discovered was that you should never write SQL. Instead, go into Access and use the Query By Example (QBE) tool to drag and drop links between columns in tables. Then copy the generated SQL as text. It is very easy to understand selects and joins if you use the visual interface.
What this says to me, is that SQL is hard because SQL is bad. The language obscures what it is intended to convey.
Ummm… how is SQL hard? It’s just about the single simplest not-even-a-language out there…
Sure it is… Just like driving a Formula One car is easy…
I’m afraid I have to disagree with Jerome. Sure, you can use Access to generate simple queries and even basic joins but it is very limited for doing anything more complex than that. There are other visual designer tools that do a better job but even they have serious limitations. Some things you just have to code by hand. I have never found a visual query generator that can even approach things like CTEs or even subqueries.
SQL isn’t hard because it is bad. SQL is hard for some people because the underlying concepts of the relational database force them to change their thought process from procedural to set based. The SQL language is a (mostly) elegant solution to handling that paradigm.
I applaud this project – what a great idea!
Yes, and yes again, Eli. I would gladly recommend this to friends who are interested – I get asked fairly often for good resources like this. I would also gladly pay a nominal fee for this kind of resource.
Nice!
Btw, to those buffoons who write that SQL is not that hard (and can be learned in a day! LOL), please list your websites or who you work for…so that I may never, ever entrust my credit card or private information to you or those you work for; like Dan Sutton 😉
Keep up the good work.
This is a great idea and I applaud you for it. When I’ve trained juniors over the years (usually helpdesk people who showed an interest) I’ve sent them an introductory ebook I’ve had for years. I will still do that but then send them to your project. Great work!
To those commenting that SQL is not hard, I would say that simple SQL is not hard, but real world applications of SQL are rarely simple. Most people try to do things with loops or “row by agonizing row” as Jeff Moden calls it. That is easy but it’s the wrong way to do it. Being good at SQL requires truly understanding set theory. It’s a serious branch of mathematics that underpins relational database theory, and if you think that’s easy as a beginner then you’re either a genius or an arrogant fool who has barely scratched the surface.
Beyond the language, when you start really working with SQL you will find that every database you come across is completely different and you’ll often have to reverse engineer the tables to create your own entity relationship diagrams and wade through stored procedures, triggers, functions, ORM code and sometimes front-end application code with inline SQL etc etc just to understand why it was designed that way and how you can work with it. You’ll also end up having to work with different vendor databases such as Oracle, postgres, MySQL, sybase, pervasive, SQL Server, DB2 and now things like HIVE and they all have their quirks and non-standard implementations of the ANSI standard SQL. Then you’ll be using procedural extensions to the SQL dialects like T-SQL and PL/SQL and it goes on.
There are no easy languages, they all take learning, practice and experience to master and any interactive learning tool like this is a blessing to those just starting out.
The SQL that is readily accessible via a query-by-design interface is also the SQL that is fairly easy to learn. For more complicated queries while you may be able to use a GUI interface to build one it is much faster to do so explicitly in text.
I don’t really have much to comment generally on this tool since I am not really its target audience and I haven’t given much thought to trying to teach others SQL.
Given a database and a desired result figuring out the needed code (SQL or otherwise) is going to be fairly doable – performance requirements not withstanding.
Instead of simply trying to teach people SQL it would seem to me that trying to teach people to solve data problems in a specific domain would provide a better approach. Think “word problems” in math instead of solving simple formulas. Creating a list of formulas to solve may help teach the mechanics but story problem solving is (I say this without proof) better for actually learning and remembering those skills in a meaningful way.
Nice!
Thanks for the additional feedback everyone, I’ve been out of town so I apologize for not getting back to everyone in a more timely fashion.
I’m going to make some tweaks to the application and my priority list based on the feedback. I also need to see if I can duplicate wazz’s issue with needing to scroll, so far I haven’t run into this issue int he resolutions I have tried, once I can duplicate it I’ll tweak the CSS to scale better to that size.
Great start!
This could turn into a very useful noob* tool.
When the more advanced topics are created, this site will also be a refresher for the experienced amateurs like me (I still need to look up INNER/OUTER LEFT/RIGHT join behavior when constructing an advanced query).
My suggestions.
1) Add a prequel to the lessons already there. Just simple, cut and paste, working queries to show results. That will give the low-confidence, “I have never seen SQL before” types immediate feedback.
2) In lesson S4.0, you jumped right into the full column name (table.column) syntax without warning. If you don’t already intend to, you really should have some single-table lessons that gently introduce the col name variations.
3) Along the lines suggested above by others, maybe a “Give me a hint” button can activate after several failed attempts. And maybe an “Okay, I give up” button after several more?
4) How about a “learn more” button/tab that displays a much more detailed discussion of the lessons topic? As the topics get more complex, I don’t think the little “instructions” box will work very well.
<sarcasm>
5) To pacify all the “SQL is easy” haters above, maybe you should re-brand this to “www.nontrival-sqlishard.com”
</sarcasm>
All in all, a great tool.
PS – Are you are interested in outside (free) help on this project. I might have some time to contribute. (If so, I assume you can get my email through this posting).
* I say noob with all respect. We are/were all “noobs” on some topic!
Thanks for the detailed feedback David. I’ve noticed several people had issues with S4.0, part of that is likely because I skipped a few intended exercises (4 is the first multi-table one and it helped me solidify what the sample tables would be and the change deployment process for generating sample data for multiple tables).
I’m not set up to accept pull requests or other forms of assistance at the moment, a lot of this is still coming together. Up until yesterday the exercises were still hardcoded into the application, but I already have some ideas on offering helpful tips (which I think would fit #1 and 3).
I like the idea behind 4 and agree the explanation box is a little limiting, but at the moment that’s also forcing me to keep these simpler. For those of us that have been doing SQL for a little while, this set of SELECT exercises will move slow, when I get some more advanced stuff in there that constraint may stop being helpful.
Really nice. I really enjoy the codecademy stuff. Can you submit this there?
On S2.6, your use of the word ‘plus’ in the question is a little confusing.
On S4.0, (as an old sql guy) I can come up with lots of answers for the question that generate the right result, but it took me a while to get the “right” result.
I assume you’ve got some sort of database with questions, and answers. Here’s a million $ idea for you…enable some framework where i can submit my sql questions and answers and license to companies that may want some special training over and above what you offer.
Along with the previous suggestion, I’d be happy to help devise questions and answers. I’m primarily an Oracle guy, so i know there’s a slightly different flavor as statements get more complex for SQL Server, MYSQL, etc. There’s lots of room for growth with stored procs, functions, triggers, indexes, dba stuff…etc.
Anyway i can print a “Completed” certificate i can show my boss or hang in my office?
Have you seen http://www.plsqlchallenge.com/ ?
Keep up the good work. Let me know if you need help with any parts.
chris: Thanks for the feedback 🙂 I don’t know anything about submitting to code academy, but there were a couple reasons I built this on my own such as not requiring registration.
4.0 does seem to be causing a lot of problems, it has the next highest error rate after 1.0 and 1.2 (which I just modified last night). 2.6 seems to be getting a pretty high rate of success (90%), so it’s lower priority to tweak at the moment.
At least for now I am not setup for taking submissions, but given the amount of feedback I’ve gotten, I may setup a feedback site to accept submissions of both new SQL statements and other features like the certificate and training ideas. Still waiting for the morning coffee to brew, so I’ll let that one simmer for a while.
I hadn’t seen plsqlchallenge, thanks 🙂
Nice idea, and a clean/cool realisation.
A few more ideas/comments that come up to my mind after a few moments with your app:
—-
1/ The menu on the could easily be hidden.
Once you start on an exercise, maybe you’ll follow one after another, no need to have that menu in this case (maybe just a reminder that pops up to see where you are, but no need to eat a third of the screen)
—-
2/ Let the user have a look at the model.
Present the user with a graph representing the model, give an overview and sample data.
Without a clear context, exercises become unecessary hard, and a bit too abstract.
A picture is worth a thousands words
This could also be a great opportunity to introduce data modeling, how and why we need relations between tables (eg: for users coming from excel/access who tend to put all data in a flat format)
—-
3/ Make instruction clear.
The text block is a bit too uniform.
User needs to see clearly the 3 sections:
– Explanations
– Example
– Exercise
Maybe use some folding panels to make a clear separation (although it woulb be cool to be able to see all three at once)
Emphasis on the text elements that matter in the exercise summary (use bold text and/or color to highlight table names and column names, much like Zelda games)
Following point #2, exercises could also provide a sample of the expected result data, this could be really useful for LEFT/RIGHT joins examples (eg: for an hypotetical RIGHT JOIN exercise, show all rows resulting from the LEFT JOIN exercise, and rule out the rows that are filtered out, helps the user spot the difference, what it really does)
—-
Keep up the good work, that’s a nice initiative, and a useful quick start for users new to SQL
Note: maybe change the name, SQL is hard indeed, but haters gonna hate 😉
Excellent work! I would suggest you put a date last updated somewhere on the page so we can tell how old the site is and when updates are done. Also, I don’t mind the “raw” interface at all. All that typing is good for memory retention. Can’t wait for an update to this site.
Nice article, but I am often amused by people not knowing the difference between “hard” and “difficult”. Granite might me referred to as hard and cotton wool might be referred to as soft, whereas applied mathemactics would be difficult for most 5 year olds to master. The opposite of “easy” is not “hard”; it is “difficult”. How difficult is that to remember? 🙂
Fabien T: Thanks for the feedback. I’m torn on the first one because I am also using the list of exercises as a visualization of the progress you’re making, I’ll think on it some more and see if I can find a way to get both. I like the visualization idea, I had considered using them in individual exercises later on, but having one for the involved tables all along would be useful. I’m adding the defined regions for the text block to the list too, I need to work out how to implement it without losing too much vertical space or making it too busy, but I agree some uniformity there would help break up the big wall of text and make it easier to consume.
Walter: Thanks, I have a version number in the bottom right that I stamp on from the build process, I’ll add in the date as well. I’ve also started using the @sqlishard twitter account to announce updates, I’ll do a follow-up post shortly with more information, as several people have asked for ways to stay up to know when exercises or features are added.
Philip: But if I had named it SQLisDifficult it would have been harder to type 😉
good idea…
SQL is not hard – it is just poorly thought of in my opinion. The proof is those crazy joins.
15 years ago, the professor teaching me the database course at university told me that soon SQL will be replaced by “Natural Language”. That was back in 1998 – 2013 and still we’re using good (or not so good) old SQL – the same SQL that we were using 15 years ago.
itoctopus: I find SQL to be a much better representation of what I need then natural language. I could only imagine how much harder it would be to debug a statement or performance tune it if it was in natural language instead of a consistent syntax with tight constraints. I believe more choices in how to represent the same query would only cause more confusion, not less (both for the user and for the engine attempting to parse and execute the query).