SELECT a.foo, b.bar, g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id
LEFT JOIN gamma g ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo SELECT a.foo, b.bar, g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id
LEFT JOIN gamma g ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo select
a.foo,
b.bar,
g.zed
from
alpha a
join
beta b
on b.alpha_id = a.id
left join
gamma g
on g.beta_id = b.id
where
a.val > 1
and b.col < 2
order by
a.foo
It's really easy, for me anyway, to get an overview of the query with this style compared to styles that are more cramped or that are inconsistently wrapped/indented.For simpler queries, I think this is okay too, but only if the clauses easily fit on a single line:
select ...
from ...
join ...
where ...https://github.com/republicwireless-open/sql-style-guide
I think Mozilla's does as well.
Where 1 = 1
And...
And...
Which makes it easy to comment out specific filters. from
alpha a
inner join beta b on b.id = a.id
left outer join gamma g on g.id = a.id
left outer join (
select z.id, count(\*) as cnt from zeta z
) delta on delta.id = a.id
where
...If there are many joins, I could also add more indention to show what is being joined to what.
SELECT a.foo, b.bar, g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id
LEFT JOIN gamma g ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo
Usually only the conditions get deep and can also use extra indented parenthesized parts.reminder: don't use 'OUTER' it's pure noise
SELECT
a.foo,
b.bar,
g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id
LEFT JOIN gamma g
ON b.id = g.beta_id
AND a.id = g.alpha_id
WHERE
a.val > 1
AND b.col < 2
ORDER BY
a.foo; SELECT a.foo
FROM alpha a
JOIN beta b ...
would become SELECT a.foo
FROM alpha a
LEFT JOIN beta b ...
Any diff tool correctly highlights the only change is the LEFT.Oddly, DataGrip doesn't provide this option.
SELECT a.foo
, b.bar
, g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id AND a.another = b.thing
LEFT JOIN gamma g ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo
or SELECT a.foo
, b.bar
, g.zed
FROM alpha a
JOIN beta b
ON a.id = b.alpha_id
AND a.another = b.thing
LEFT JOIN gamma g
ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo
I'm not consistent with the layout of my joining predicates - I go for whatever seems clearer given the current circumstances and that varies due to several factors (number of parts, length of column names and/or functions, ...). How sub-queries and instances of CASE are broken into lines and indented is something I also vary on. SELECT a.foo, b.bar, g.zed
FROM alpha a
JOIN beta b ON a.id = b.alpha_id AND a.another = b.thing
LEFT JOIN gamma g ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo
(bonus: "AND" got accidentally aligned with the end of "WHERE")I use tabs.
SELECT t.foo, t.bar
FROM a_table tI can see why. The indentation of the whole statement is not determined by the first line, but by the 6th on the first and the 8th on the second on a `JOIN` clause. It's really arbitrary, and when you have that statement between other code, it's going to be weird how the start of the statement is much more indented than its preceding code. I really dislike it, too.
I prefer the use of indentation to signal what's inside another syntax structure. So, for example, I also dislike how you aligned `ON` and `AND` when the `AND` is inside the `ON` expression. It makes it seem like the two lines are on the same syntactic level.
Here's how I do it:
SELECT a.foo
, b.bar
, g.zed
FROM alpha a
JOIN beta b
ON a.id = b.alpha_id
AND a.another = b.thing
LEFT JOIN gamma g
ON b.id = g.beta_id
WHERE a.val > 1
AND b.col < 2
ORDER BY a.foo
You might also notice that I removed the padding you used to align the `=` signs. I dislike big changes where the only thing that changed for a line is the whitespace padding. It obscures the real change. It might not seem like a big thing when you only have 2 lines in alignment, but it's a real bother when reading a diff that does that for more lines. You have to compare between the - and + lines to find what really changed instead of the diff telling you outright.In many circumstances (chunks of SQL in SSIS steps and so forth) there is no code to be around. Within longer tracks of SQL I'll not let "LEFT OUTER JOIN" push the whole statement to the right, but will drop the table name to the next line and maintain the alignment from there on.
> removed the padding you used to align the `=` signs. I dislike big changes where the only thing that changed for a line is the whitespace padding. It obscures the real change
For modifying existing code, I will sometimes let the alignment slide to avoid unnecessary extra lines of change. Though a good visual diff tool will have the option to ignore white-space-only changes and I'm not concerned about patch sizes being a few lines bigger.
To fix the alignment there may be a subsequent check-in that tidies up non-functional elements of the code. I'm happy to have an extra item in history in order to maintain readability over a stream of unaligned text.
Something I've wanted for a long time in code editors is for tabs after the first non-whitespace character on a line to line up, that way such alignment could be managed without extra effort or extra lines in a diff. There would need to be some simple heuristics to control breaking the alignment (and these may need to vary between languages) and perhaps some way to control/override them (a directive in comments?) in edge cases.
select
a.foo
, b.bar
, g.zed
from alpha a
inner join beta b on
b.alpha_id = a.id
and b.thing = a.another
left join gamma g on
g.beta_id = b.id
where
a.val > 1
and b.col < 2
order by
a.foo col1,
col2,
col3
col1
,col2
,col3
You can remove col2 from either of those examples and have valid syntax.My job involves a lot of ELT pipelines though and the queries I'm writing are often to transform a client's data from whatever ill-conceived data model they've been using to a standard data model that we use for all clients. Those queries require a lot more "detective work" to get right than the queries that run against our standard data model. If I was just writing queries against the standard, I'm not sure I'd spend enough time developing/debugging to really notice any ergonomic benefit.
What happens is I want to comment out a join entirely, and all its columns. I rarely find myself commenting out the first column. I'd prefer trailing commas on every element, where allowed, to be sure! but leading isn't so bad once I got used to it.
Plus to scan for a missing leading comma is a linear (literally!) search whereas [missing] trailing commas don't line up.
SELECT a.foo
, b.bar
, g.zed
FROM ...
While the comma placement may seem weird, it makes this exactly identical to the "AND" or "OR" placement in WHERE clauses, and the primary benefit is that it's easy to comment out any column except the first.It's not completely unconventional. Haskell is typically styled with that kind of comma usage, too. For example,
[ 1
, 2
]
{ foo = 1
, bar = 2
}
Coincidentally, SQL and Haskell are the only languages I know that use `--` for comments.(Edit: I think I misread “know” as “know of”; whoops.)
Don't worry about it; you didn't misread. I wasn't aware of AppleScript and HyperTalk, and though I read a bit on Lua some years ago, I either forgot or never realized that it used `--` for comments.
Personally I don't think that optimization is worth the price. Trailing commas look nicer visually so I prefer them.