News for hackers. Stuff that matters.
Re:Writing more legible SQL by combatentropy on Thursday November 03, 2016 @01:27AM (#12861805)
Here is how I write SQL:

    select
        t1.col1,
        t2.col2,
        t3.col3
    from table1 t1
        join table2 t2 on t1.col2 = t2.col1
        join table3 t3 on
            t1.col3 = t3.col1 and
            t3.col2 = something_else
    where
        t1.col1 > 0 and
        t2.col2 <> t1.col4
    order by col2
    limit 100
So:

1. SQL capitalization is not sacred. I lowercase everything.

2. I just indent subclauses, with four spaces, like I indent other languages. I don't go out of my way to line up things vertically.

3. Conjunctions like "and" are put at the end of a line, like a comma, not at the beginning. I think it lines things up better vertically.

4. I try to keep lines short, but I also try to keep it from getting needlessly long vertically. So if the statement is short and simple, I might fold some things back onto one line, like:

    select col1, col2, col3
    from table1
    where col1 = something_or_other

or even:

   select * from table1 where col1 = something
Re:Writing more legible SQL by vog on Thursday November 03, 2016 @04:47AM (#12862417)
I fully agree with the sentiment, and especially with treating SQL code as code, because it really is code. My style differs in 4 regards:

1. "join"s are at the same level as "from", and the contents of from/join are indented

2. prefer tuple comparisons of multi-comparisons, i.e. "(a,b)=(c,d)" instead of "a=c and b=d"

3. operators auch as "and" are at the beginning of a line, as in style guide of almost all other programming languages, too

4. the contents of "order by" and "group by" are also indented, the same way as the "select" columns

Example:

    select
        t1.col1,
        t2.col2,
        t3.col3
    from
        table1 t1
    join
        table2 t2 on t1.col2 = t2.col1
    join
        table3 t3 on (t3.col3,  r3.col2) = (t1.col3, something_else)
    where
        t1.col1 > 0
        and t2.col2 <> t1.col4
    order by
        col2 asc,
        col1 desc
    limit 100
Re:Writing more legible SQL by snarfy on Thursday November 03, 2016 @10:52AM (#12864413)
For item 3, the benefit of "and" at the beginning is that you can add or remove lines to the condition without disturbing the previous/next lines. The same works for ","
Re:Writing more legible SQL by vog on Thursday November 03, 2016 @11:31AM (#12864794)
But the disadvantage is that you don't immediately see whether it is "and", "or" or something else.

That's why in most programming languages the coding style says you should put the operators at start of line instead of end of line, e.g.

GOOD:

    if ((...some_condition_that_may_make_sense...)
        && (...some_other_condition...)
        && (...and_yet_some_condition_that_makes_sense...))

    x = ((some expresssion)
         + (some other expression of different length)
         - (some final expression))
BAD:

    if ((...some_condition_that_may_make_sense...) &&
        (...some_other_condition...) &&
        (...and_yet_some_condition_that_makes_sense...))

    x = ((some expresssion) +
         (some other expression of different length) -
         (some final expression))
Examples:

- Python PEP-0008: "Should a line break before or after a binary operator?" https://www.python.org/dev/peps/pep-0008/#should-a-line-brea...

- Topvoted SO answer for "If you break long code lines, how do you indent the stuff on the next line?" http://stackoverflow.com/a/699347

Re:Writing more legible SQL by rubyfan on Thursday November 03, 2016 @07:25AM (#12863017)
Very similar to my style, though I rarely use <> and instead mostly use !=

Never realized I could do tuple compare and will probably adopt that.

Re:Writing more legible SQL by combatentropy on Thursday November 03, 2016 @02:32PM (#12866617)

  >> prefer tuple comparisons of multi-comparisons,
  >> i.e. "(a,b)=(c,d)" instead of "a=c and b=d"

    > never realized I could do tuple compare and
    > will probably adopt that.
Indeed. Mind blown.
Re:Writing more legible SQL by gerhardi on Thursday November 03, 2016 @05:00AM (#12862448)
I always keep the joins indented from the table that they are joined to:

  select    t1.col1,
            t2.col2,
            t3.col3,
            t4.col4
  from      table1 t1
                join table2 t2 on t2.colx = t1.colx
                join table3 t3 on t3.coly = t1.coly
                    join table4 t4 on t4.colz = t3.colz
                join tablen tn on tn.coln = t1.coln
  where     tn.colnx in (...)

            -- Table 3 and Table 2 have some values while Table n value is not something OR Table n has value that is exactly something
            and (
                    (t3.col = x and t2.col = y and tn.col != z)
                    or 
                    tn.col = z
                )
  ...
So in above you can see by the indent on which table some other table is joined to. Tables t2, t3 and tn are related to t1, but t4 is related to t3, not directly t1.
Re:Writing more legible SQL by vog on Thursday November 03, 2016 @05:51AM (#12862626)
> indented from the table that they are joined to

There is not always "the" table.

How does your coding style work if you join into multiple tables? (because in reality you join the new table with the joined result of the previous tables, and hence can reference any combination of any previous table columns, unless you group your joins with parentheses)

  select
      ...
  from
      table1 t1
  join
      table2 t2 on t2.colx = t1.colx
  join
      table3 t3 on (t3.coly, t3.colz) = (t1.coly, t2.colz)
Re:Writing more legible SQL by gerhardi on Thursday November 03, 2016 @07:05AM (#12862899)
What you are saying is correct. In this case I would have the join of t3 on the same indent level as the join of t2 as t3 table has also the common key with t1. Somehow I just find the parent comment style not so intuitive for me.
Re:Writing more legible SQL by bhrgunatha on Thursday November 03, 2016 @06:00AM (#12862660)
I much prefer the style of the comment you replied to because it's very easy (for me) to scan the table/view names when they are vertically aligned.

They are at the top of the hierarchy of information I want when I'm reading a query.

The information I want to be able to identify the quickest are.

1. Tables/view names

2. How they are joined

3. Columns

4. Filters

5. Grouping/Ordering/Anything Else

Re:Writing more legible SQL by sevensor on Thursday November 03, 2016 @12:18PM (#12865308)
Regardless of the particulars, I find the most important thing for readability is for the author to have made some kind of decision and stuck to it. The most illegible style is no style at all.
Re:Writing more legible SQL by hiou on Thursday November 03, 2016 @01:20PM (#12865953)
As long as it does not deviate into getting really creative with the spec, keeping everything consistent is overrated in my opinion.

There are the exceptions of very widely used projects where contributors will only look at the code a couple times when making a change to be pushed upstream or where there are significantly junior developers that need a narrow scope of the language to help them with the learning curve and getting up to speed with the code base.

In my experience(which is very anecdotal I admit), the requirement for consistency is more about a particular personality trait that many developers have - the need for order and control - as opposed to a requirement for quality production code.

Re:Writing more legible SQL by ckastner on Thursday November 03, 2016 @10:52AM (#12864412)
Where did you pick up this style?

I have been following this pattern for over a decade. I believe I picked it up from some project's style guide, but I never found it again.

Re:Writing more legible SQL by cptskippy on Thursday November 03, 2016 @10:18AM (#12864094)
If I came across your SQL, I'd probably hunt you down and give you a hug. There's so much horridly formatted code and it's unusual to see a developer care.

I prefer to uppercase command syntax to make stand apart visually from the parameters of the query. I don't agree with your conjunctions at the end of the line, I actually prefer commas at the beginning of the next line though I don't do that so as to conform to convention. I also use the AS keyword to explicitly denote aliases.

If I had it my way, all SQL would look like this:

    SELECT t1.col1
          ,t2.col2
          ,t3.col3
    FROM table1 AS t1
    JOIN table2 AS t2 
        ON t1.col2 = t2.col1
    JOIN table3 AS t3
        ON t1.col3 = t3.col1
        AND t3.col2 = something_else
    WHERE t1.col1 > 0
        AND t2.col2 <> t1.col4
    ORDER BY col2
    LIMIT 100
Re:Writing more legible SQL by sbuttgereit on Thursday November 03, 2016 @11:54AM (#12865055)
Very much like this style, very close to what I do... really the only difference between your style and mine is that I will indent the joins. For me it makes it somewhat easier to be able to scan for the where clause. Also I'll typically not use the AS keyword for table aliasing, no real good reason for that choice other than many years of habit.

But mostly commas first and logical operators and such first: If I have complicated queries that I'm working through... having the ability to just comment bit out here and there without worrying too much if I've left a dangling comma (et al) is a good time saver.

Re:Writing more legible SQL by cwyers on Thursday November 03, 2016 @11:34AM (#12864825)
That's pretty close to how I do it. I started putting commas at the beginning of a line because when I started doing so I stopped ever having queries error out because I copy and pasted something from one query to another and forgot to remove a trailing comma. Having the commas at the front of the line makes finding those kinds of errors automatic for me.
Re:Writing more legible SQL by blakeyrat on Thursday November 03, 2016 @03:48PM (#12867321)
Instead of using uppercase, which looks awful, just get an editor with color-coding. Solves the same problem, no more ugly uppercase.
Re:Writing more legible SQL by lost_my_pwd on Thursday November 03, 2016 @06:44AM (#12862798)
That matches what I do pretty much with the exception of capitalization. I agree, it's not totally necessary, but it does provide a visual delineation of each section/component of the the statement, which, for large statements, can be very helpful in quickly scanning what it does:

    SELECT
        t1.col1,
        t2.col2,
        t3.col3

    FROM
        table1 t1
        join table2 t2 on t1.col2 = t2.col1
        join table3 t3 on
            t1.col3 = t3.col1 and
            t3.col2 = something_else

    WHERE
        t1.col1 > 0 and
        t2.col2 <> t1.col4

    ORDER BY col2
    LIMIT 100
    ;
Re:Writing more legible SQL by mozumder on Thursday November 03, 2016 @06:49AM (#12862810)
The lower-case probably works better for IDEs that have SQL syntax-coloring. If your IDE doesn't have that (looking at you XCode..), then upper-case keywords are better.
Re:Writing more legible SQL by bluedino on Thursday November 03, 2016 @07:37AM (#12863092)
>> If your IDE doesn't have that

I'm looking at you, System i Navigator. Also you don't support anti-aliased fonts or scale properly (because you're a 90's Java application)

Re:Writing more legible SQL by biztos on Thursday November 03, 2016 @10:32AM (#12864207)
I do almost the same thing, but I capitalize all SQL keywords. I'm sure that's annoying to someone somewhere but I find it useful in separating the SQL from the relation names.
Re:Writing more legible SQL by WorldMaker on Thursday November 03, 2016 @05:11PM (#12867990)
We've had great syntax highlighting tools for decades now, I'd much rather my tooling do it for me with subtle colorations than be forced to resort to COBOL SCREAMING.

I've trended towards a preference to "sentence-cased" SQL where the first word in an SQL statement is Capitalized and everything else is lower-cased. Makes things read more like a narrative and is a nicer hint than trying to spot an optional semi-colon to determine if you've reached the end of a command yet (and helps in those times when you need to find a place where it turned out an optional semi-colon wasn't in fact optional).

    Select *
    from table
    where condition
    order by fields

    Insert into table
      (...)
    values
      (...)
So far as I know I'm about the only person that likes sentence-casing SQL, but it helped me out quite a bit on some projects I worked on and it kept things readable.
Re:Writing more legible SQL by specialist on Thursday November 03, 2016 @09:12AM (#12863634)
+1 Vertical whitespace.
Re:Writing more legible SQL by gbog on Thursday November 03, 2016 @10:41AM (#12864290)
yes, neat, and yes SQL is code. Problem is that there is not SQL linter I know of.
Re:Writing more legible SQL by __jal on Thursday November 03, 2016 @09:33AM (#12863762)
Yep. Same here. I find screaming one's reserved words far more distracting than the highlighting helps.

Another SQL habit that seems to far more annoying than helpful is putting commas at the start of next line. Great, they line up. Did you know that publishers have a term for vertical patterns in blocks of text? They're called 'rivers', and one generally attempts to avoid them, because they're visually distracting.

Re:Writing more legible SQL by blowski on Thursday November 03, 2016 @09:45AM (#12863867)
One developer's 'river' is another's 'grid'. Being able to scan down quickly makes it easier to compare lines against each other. That's not something you do when reading a novel or a newspaper article, but it's something you do all the time when reading code.
Re:Writing more legible SQL by __jal on Thursday November 03, 2016 @10:03AM (#12863984)
Maybe I'm a weirdo. I find it massively distracting. About the only time column-alignment is helpful is when scanning for typos, but that's handled pretty capably in other ways by most editors more sophisticated than Text Edit.
Re:Writing more legible SQL by gbog on Thursday November 03, 2016 @10:48AM (#12864357)
I think "rivers" are not the same. if the same as in edition of books in French, rivers are those unwanted "paths" your eye sees floating downwards inside the rectangle of words that makes a page. They come out of randomness, when whitespaces happen to draw a negative path. It has to be corrected by slightly modifying the whitespaces between some words. AFAIK this is done manually and is one reason for book edition to be done by humans.

In short, it has nothing to do with purposeful perfect vertical alignment in code.

Re:Writing more legible SQL by __jal on Thursday November 03, 2016 @11:51AM (#12865020)
When I worked in magazine production (90s, California) we used the term for both whitespace and other patterns. Other patterns are a lot less common, because whitespace is the most common "character", but they happen.
Re:Writing more legible SQL by irrational on Thursday November 03, 2016 @01:52PM (#12866252)
I used to agree with you about putting commas at the beginning of lines, but now I've changed my mind. By putting the commas at the beginning of lines it becomes much easier to do dynamic sql and to be able to add remove select statements without having to check the ends of the lines to make sure the last line does not have a trailing comma and to make sure the preceding lines each does have the requisite comma.
Re:Writing more legible SQL by rubyfan on Thursday November 03, 2016 @01:49AM (#12861871)
I go back and forth with conjunction at the end or beginning of the line. At the end you get to line up column names, at the beginning it makes it easier to comment out or remove the line and basically contains the intended logic on a single line.

I think I usually end up with the later because I think it makes more sense.

Re:Writing more legible SQL by berntb on Thursday November 03, 2016 @05:26AM (#12862526)
Why not this?

  WHERE A
    AND B
    AND C
Or better, this? You can comment out any part easily.

  WHERE 1
    AND A
    AND B
    AND C
(With keywords capitalized, as g-d intended. :-) Or not.)
Re:Writing more legible SQL by nerdponx on Thursday November 03, 2016 @07:02AM (#12862885)
I like the "WHERE 1" trick, thanks!
Re:Writing more legible SQL by bhrgunatha on Thursday November 03, 2016 @06:10AM (#12862693)
I have the same problem and also with where to put the commas separating columns names. You can't win the game though.

Sometimes you want to remove/comment out the first line, sometimes the last, sometimes one in the middle.

Re:Writing more legible SQL by jm547ster on Thursday November 03, 2016 @02:26AM (#12861981)
"2. I just indent subclauses, with four spaces,"

Surely you mean tabs? runs

Re:Writing more legible SQL by Sean1708 on Thursday November 03, 2016 @09:37AM (#12863799)
"runs"

Into my arms.

Re:Writing more legible SQL by walrus on Thursday November 03, 2016 @02:01AM (#12861899)
Interesting! I independently ended up on nearly the exact same style. The only difference is I don't indent join clauses.
Re:Writing more legible SQL by irrational on Thursday November 03, 2016 @01:42PM (#12866165)
I prefer putting the comma at the beginning of the line (this makes dynamic sql much easier). I prefer putting and/or at the beginning of the line. I indent multiple items like case statements in the select. I use parens for join statements with multiple join conditions. I separate the select/from/where clauses with a blank line when a section has more than one line.

select

t1.col1

, t2.col2

, t3.col3

, (case when t1.col1 = 'Y'

   then '1'

   else '0'

   end) as the_flag
, t3.col2

from table1 t1

join table2 t2 on t1.col2 = t2.col1

join table3 t3 on (t1.col3 = t3.col1

   and t3.col2 = something_else
)

where t1.col1 > 0

and t2.col2 <> t1.col4

order by

col2

, col1

limit 100

Re:Writing more legible SQL by alistairbayley on Thursday November 03, 2016 @04:15AM (#12862313)
1. Why indent the joins? Are table2 and table3 less important than table1? Is table1 special? Is that why it enjoys privileged status in the from-clause?

2. Why place some predicates in the where-clause and others in the join-clauses? What's the thinking here? Why not put all predicates up in the join-clauses, nearer to the tables that they affect?

Re:Writing more legible SQL by 83457 on Thursday November 03, 2016 @04:41AM (#12862406)
I think of joins as operators and from as the block similar to and/or in the where clause. He is being inconsistent with line breaks for select, from and where blocks. Personally I want to be able to visually pick out the blocks of the query and the easiest way to do that is with indention imo.
Re:Writing more legible SQL by 1wd on Thursday November 03, 2016 @08:01AM (#12863241)
If "joins" are operators like "and", and you put "and" at the end of the line, shouldn't you put "join" at the end too?

    from
        table1 t1 join
        table2 t2 on t1.col2 = t2.col1 join
        table3 t3 on
            t1.col3 = t3.col1 and
            t3.col2 = something_else
Re:Writing more legible SQL by 83457 on Thursday November 03, 2016 @09:50AM (#12863902)
well I don't put and/or at the end of lines so there is that... but I have seen people but joins at the end of lines
Re:Writing more legible SQL by 1wd on Thursday November 03, 2016 @02:05PM (#12866372)
sorry, mistook you for the top-level poster.
Re:Writing more legible SQL by combatentropy on Thursday November 03, 2016 @03:16PM (#12867059)

  > Why indent the joins?
  > Are table2 and table3 less important than table1?
It's often arbitrary which tables are joined and which one is from'd. But the joins are part of the from-clause. They all join together into one big from.

  > Why place some predicates in the where-clause and
  > others in the join-clauses? What's the thinking here?
  > Why not put all predicates up in the join-clauses,
  > nearer to the tables that they affect?
The join conditions are just to line up the rows of the different tables with each other, to avoid a cartesian product, to form one big table.

This giant table is then filtered through the where-clause, like a funnel. You can put the filters in the joins, and I have in the past, but putting them in the where-clause better reflects the picture in my head.

Tangentially, it would have been better if SQL had the select-clause after the from- and where-clauses:

    from table1 t1
        join table2 t2 on t1.col2 = t2.col1
        join table3 t3 on
            t1.col3 = t3.col1 and
            t3.col2 = something_else
    where
        t1.col1 > 0 and
        t2.col2 <> t1.col4
    select
        t1.col1,
        t2.col2,
        t3.col3
To understand the select-clause, I always first have to jump down to the from-clause anyway. This would also mirror the other statements: insert, update, and delete, which begin with the table names.

This better reflects the flow of data. First you decide the source of data (which tables). Then you filter down to which records (which rows, the where-clause). Finally you determine which fields to get (which columns, the select-clause).

Re:Writing more legible SQL by matwood on Thursday November 03, 2016 @08:41AM (#12863470)
I've been writing SQL for close the 20 years, and my style has settled into something very similar to yours. Lowercase everything, and use indentation to clearly separate the major parts of the query.

And, like you, be pragmatic. If it is a 1 liner, keep it a 1 liner.

Re:Writing more legible SQL by logingone on Thursday November 03, 2016 @09:21AM (#12863681)
I read somewhere, at some point, couldn't provide a ref, that the caps were used for clarity back in the days of monochrome screens. Now, with colour syntax highlighting it's no longer as useful.
Re:Writing more legible SQL by BurningFrog on Thursday November 03, 2016 @03:30AM (#12862173)
The purpose of capitalization is to visually distinguish the keywords.

In this style that's done in other ways so there is no need.

Re:Writing more legible SQL by neves on Thursday November 03, 2016 @10:18AM (#12864096)
You didn't mentioned the most important thing to make readable SQL and that is demonstrated in your clause: use the "join" keyword instead of doing the join in the "where" clause.

I can always auto-reformat a complex SQL in a IDE, but if it isn't using join clauses, it will stink.

Re:Writing more legible SQL by sundvor on Thursday November 03, 2016 @10:28AM (#12864161)
My first thought was "why would you do that?". Glad to say I've rarely seen joins in the where clause.
Re:Writing more legible SQL by T-hawk on Thursday November 03, 2016 @03:10PM (#12867002)
This is what he means, and I see it all the time: SELECT FROM table1 JOIN table2 WHERE table1.field = table2.field

An unsettling number of SQL developers never actually learned join syntax and write it that way.

It's functionally equivalent to putting the equality in the JOIN ... ON clause, and any modern database will optimize it to execute the same way, but it's a worse syntactical representation of what's actually happening.

Re:Writing more legible SQL by sundvor on Friday November 04, 2016 @04:47AM (#12871141)
Great, thanks for that - I've been using (typically INNER) JOIN .. ON .. for all my life, well 20 odd years of development, and not once did I ever put the ON clause into WHERE. :)

I can vaguely recall seeing it a few times now, actually, and being rather confused as to why you'd do it that way - as perhaps it was a more optimal way of putting it, and that I'd done it wrong all the time?

As you state though, it's just bad; WHERE clauses ought to be used for filtering the data, not declaring how the tables join. Glad to have cleared that up. :)

Re:Writing more legible SQL by T-hawk on Friday November 04, 2016 @07:11PM (#12876998)
You'd do it that way if you just didn't know any better. "Two tables where A = B" falls into a natural line of thinking for someone who picked up SQL ad hoc rather than formally learning what a join is and the syntax for it.
Re:Writing more legible SQL by sunjain on Thursday November 03, 2016 @08:39AM (#12863460)
Totally agree..This should be put on a page published somewhere. Whenever I am trying to look at performance issues (or any other issue) with a SQL, this is the first thing I do and pretty much follow the same strategy.
Re:Writing more legible SQL by julochrobak on Thursday November 03, 2016 @03:00AM (#12862079)
quick question about the indent of subclauses. How would you write a query where table3 needs to be joined with both table1 and table2? Would it change anything?
Re:Writing more legible SQL by combatentropy on Thursday November 03, 2016 @07:30PM (#12869065)
No. I indent all joins to the same level, regardless of the join condition. The effect of joins is to make one large flat table, so nested indentation is an unnecessary and misleading signal.
Re:Writing more legible SQL by emmelaich on Thursday November 03, 2016 @01:53AM (#12861877)
Oh yes please. Capitals just make it harder to read.