What's the strangest code you've seen a senior developer write? (2019)
quora.com
quora.com
Figured out LEFT JOIN eliminated all of those and produced what I want.
Had been using LEFT JOIN since. I ever remember only one time when I didn't use left join, because that case needed a full join.
Using left joins exclusively feels like it's papering over a larger issue that should be addressed.
As far as I'm concerned, LEFT JOIN is simply shorthand for LEFT OUTER JOIN, and is semantically equivalent to a RIGHT JOIN, but with the order of the tables reversed. If what you really need is an INNER JOIN, and you use a LEFT JOIN instead, then you have a load of processing to do on the result-set.
So if this guru "Jared" is only ever using LEFT JOIN, then either he's addressing a rather constrained problem space, or he's isn't that much of a SQL guru. Maybe he designs schemas in which LEFT joins are always equivalent to INNER joins?
[Edit] I'm wrong; you can, of course, get the effect of an INNER JOIN by using a LEFT JOIN with a NOT NULL join condition. But I find the latter hard to read: there must be some reason this guy has used an outer join here, when it looks as if an inner join fits the bill?
If you're writing code, you're strategy is clearly better because it documents an expectation.
If you're dropped in a database which is unknown territory, say to debug an issue, left joins represent a conservative guess, maybe even allowing to follow up with verification querys: where right join side is null.
I'd read the different responses here as people having different roles.
I've done it a few times, typically in a situation where some random contractor dropped a minimal effort database design right into production. No constraints like not null of course, that would mean the application shows an error and contractor can't have that because it would imply they did something bad.
So the DB chugs along for months, accreting damaged data. Then something finally crashes bad enough to wake up the management, which instantly switches from 'everything is perfect lalalalaaa' messages into blind panic mode.
So you get thrown into the mess, sometimes without even knowing what the application is supposed to do, with the directive: Fix this, we're bleeding money. After looking around for about 5 seconds, it turns out everything is objectively wrong. You can't fix all fires at the same time, you have to put out one at a time, and try not to make it accidentally worse. That's when you use left joins as a conservative guess, at least until you've built up enough knowledge.
This makes it sound more mysterious than it is. Joins does not have side-effects, they are just different operators. It comes down to if you want to include unmatched rows. Left join: Include unmatched rows from the first table. Right join: Include unmatched rows from the second table. Outer join: Include unmatched rows from both tables. Inner join: Don't include any unmatched rows.
Left and right join is of course the same, the only difference is in which order you list the tables. Left join seem more intuitive to me when writing queries, but logically they are equivalent.
Left joins express "Give me these things, and these other sub-things related to them". Object oriented programming lends itself towards the thing-with-subthings (and collections of things-with-subthings) so I feel that the left join is the default choice for most applications which are structured with the classic OOP approach.
I wonder if full joins are more common in other programming paradigms, such as whatever those crazy lisp folks talk about.
OTOH, if I wrote my SQLs in that fashion during data science interviews, these young “scientists” will tell me I am a novice.
There's a right, and wrong, time for using left joins. "all the time" is the wrong time. If you need to join on all existing records, including null records, you need the trinary equality operation.
Also... there's a right join... if you're writing complex enough stuff long enough, you'll eventually hit a query where it's just easier to do the same thing you've been doing on the right side.
I can't say for sure, because it's implementation dependant, but this is going to slow down your results on larger data sets as well, since you won't be excluding joins (in memory) by excluding data (during the selects from individual tables)
If you are right handed, and have a practice to write the joins in the direction one->many (or person->children, or in the opposite direction of a foreign key) then you will always write the join as:
from person join children
Then, if you are not a beginner and know a bit about nulls and their side-effects, the best thing that you can do to prevent the risk of missing data is:
from person left join children
Why? Because this will help so that you will never miss those persons that do not have children.
So, depending on the type of the application, it may be the case that outer joins are nearly always needed and it maybe be a part of quality assurance policies to always do a left join, so that most queries are easily readable by most of the team.
If you are left handed, then perhaps you will write the same query as:
from children right join person
full outer join is not needed at all if you have enforced referential integrity everywhere - you will only need a left (or right) outer join (depending on the left-to-right or right-to-left reading preference)
in databases that do not have referential integrity enforced on all true foreign keys, full outer join will probably be the only right type of join. Otherwise, you will have problems with many scenarios.
Do you have any data on the handedness of people affecting the directing in which they write joins? It seems a strong enough assertion that somebody should have done research.
That just can't be right. Great SQL people understand set theory, query planning, and a lot of arcane RDBMS internals that most of us don't have to get into.
I studied databases in college and have been writing SQL for 25 years, and I am regularly blown away by the knowledge people demonstrate on Stack Overflow.
There is just no way a great DB architect or SQL programmer would only use left joins. The person who wrote this is likely just early enough in their career that they don't know what a truly great DB expert looks like.
Your likely misinterpreting what the author means with great.
If your not at a scale where a team is pushing the micro optimization boundary, there is tremendous value in the ability to keep everything simple. Having the entire org operate using the same frame is great.
What's more, it's not uncommon for great simplicity to be mistaken for 'obvious', and excessive complexity be mistaken for great work.
This has greater value than perf for a lot of orgs.
I suspect that they were 18 in 2012 based on profile, so their career has been 10 years long so far.
As far as no great would do X, not sure (as I avoid the relational DB side of things), but sometimes experts in a thing decide to only use a subset of the capabilities for personal preferences or because they feel it makes them more productive. So maybe in this guy's mind there was an SQL: the Good parts! which only included left joins.
I am a reformed MySQL user, but one of my overly-normalized MySQL DBs has been running in production for almost 10 years without any optimization of queries, tables, or indices (beyond some naive indices I created when deploying it).
My point is that you can throw an excellent RDBMS onto some decent hardware and serve millions of requests for a CRUD web app without really thinking too hard about it.
In any case, all the joins are just syntactic sugar over cross product. AFAIK SQL did not have the join syntax initially, you just did SELECT foo, bar WHERE foo.id = bar.foo_id
Not really; using left joins enforces a specific table order in the query plan.
It's possible to optimally use left joins because one can either guess the optimal order (which is a bad habit, though), or can observe the query plan and emulate it.
My guess that this developer didn't trust the optimizer to do a good job at ordering, and he wanted to enforce it, but that is generally not the case with modern engines (of course, there will always be exceptions).
In my experience, the exceptions are more than the straightforward queries I can write and forget, so much that SQL grammar feels like the German grammar: Here's what you use in this scenario, except [goes on to list a million exception cases most of which makes no logical sense].
This is especially true if you are doing complicated queries across products in a multi-product multi-tenant multi-team database. Writing the idiomatic query takes a few minutes, then hours of fighting against the query planner.
Going bonkers with left joins and/or CTEs usually "fixes" the "problem". I usually leave a commented-out sane version after me for the people who can do better, and not to be blamed with writing mortgage-code.
Neither German nor SQL (with any RDBMS) is my native language anyway, so I can publicly admit my struggles without feeling too embarrassed :)
Absolutely not. All joins can be related, or explained by using left join as a reference, but there's no such thing as a "default join", or perhaps there is, and it's up to the implementation of the database. Taking the analogy further, all joins are outer joins, just apply some filters, right? Or a left join is just an inner join, and then you include the rest of the left table. It's worthwhile pondering about this, but "all joins are just a left join" is a moot point.
This comes up for me most often with views, when a query referencing the view doesn't end up using all the columns - when a LEFT JOIN is used, the database can potentially skip querying those tables entirely, but not with an INNER JOIN.
The more ways you do thing the more complexity you add to the code. If you have a project with the same patterns over and over again it becomes easy to learn and easy for Juniors to contribute to.
My perspective is that the left join is essentially null coalescing for relational systems. Only in queries where the joined table contains optional facts would a left join be required.
Our system is very consistent throughout, so only a few classes of joins actually need to be left joins. Despite this, we are using it in a lot of other places than would otherwise be required.
At this point, I am perfectly happy staying out of the way because others on the team are producing useful SQL. It might not be to my exact preferences always, but it gets the job done regardless.
Why not just use the non-leaky abstraction “always use left joins” and then an entire class of errors and discussions can be avoided?
Increasingly as I get older, I see the job of architect as “have conversations for the last time” so that devs can focus their “conversation quota” on the things that can’t be avoided, thus moving faster.
This is why I am happy to stay out of the way of others. If I were to impose a strict "always use left joins", there would be a different problem of similar flavor.
There are some team members who prefer to be more precise with the intent of their joins, and others who prefer to be more defensive. As long as the end result is as desired, I am happy and the customer is happy.
What I focus on the most throughout is making sure that any non-malicious query can run without worrying too much about performance. We scope our data sets so that even recursive table scan scenarios can complete within seconds. This eliminates the most onerous class of discussions in my experience - those of premature optimization.
A left join always returns at least a row; when there is no match, the part of the result (if selected) that corresponds to the right table, has NULLs.
There are many important consequences of this, one of which is that left joins enforce table ordering; inner joins can be reordered by the optimizer if iterating them in a reordered way gives faster access (imagine two nested for loops, and swap the inner loop with the outer one).
In contrast, you have 4 more Joins: the Right Join is identical to the Left Join, except that it flips the direction, so it's never necessary.
An Inner Join will only return rows that match the condition in both tables, similar in concept to a set intersection. This is a very commonly useful operation, but it can be replaced by something like "select * from tableA left join tableB on $condition where tableB.Column is not NULL".
Then, there is the "Full Outer Join", which gives you all rows in both tables; all of the rows that match appear only once and have all columns filled in, while all those in tableA that don't match still appear, and same for tableB, with NULLs for the columns of the other table. This can be obtained by doing a UNION of (tableA left join tableB) and (tableB left join tableA).
Finally, there is the cross join, which is basically the cross product of the rows of the two tables. That is, for each row in tableA, you get a row with columns set to the values of that row in tableA, and then the columns from tableB set to the values of each other row in tableB (so, you have m*n rows, if tableA has m rows and tableB n rows). This is very very rarely useful in practice.
Different types of joins exist for a reason - they address different requirements.
Using one type of join even when those different requirements need to be met is suboptimal.
In LEFT JOIN's case, it's usually not fatal (i.e. completely unable to meet the requirements) but it will definitely make things perform slower, be more complex to maintain, be harder to explain why it was chosen to other engineers (see OP), etc.
Don't leave tools in your toolbox.
There is nothing wrong with it per se, it depends on the question you are trying to answer - gauging someones competence based on the absolute number of times someone uses a left join, vs right join, vs outer join during their career is silly - almost any query can be written multiple ways to get the exact same results. What matters is did the developer get the correct results.
It's good to have a sense of what other join types do, but if they don't get you to the answer you want any faster or better, so what?
How would you feel about a programmer that solely uses `nand` as boolean operator, or `<` as relational operator, expending some effort to transform any expression from the domain so that it conforms to this stylistic restriction?
EMPLOYEE_ID EMPLOYEE_NAME MANAGER_ID
----------- ------------- ----------
1 Alice the CEO NULL
2 Bob the Director 1
3 Charlie the Grunt 2
We can get all employee-manager relationships with an inner join that finds every pair of rows in the table where the MANAGER_ID on one row matches the EMPLOYEE_ID on the other: SELECT emp.EMPLOYEE_NAME, mgr.EMPLOYEE_NAME AS MANAGER_NAME
FROM EMPLOYEES AS emp
INNER JOIN EMPLOYEES AS mgr
ON emp.EMPLOYEE_ID = mgr.EMPLOYEE_ID
which produces this: EMPLOYEE_NAME MANAGER_NAME
------------- -------------
Bob the Director Alice the CEO
Charlie the Grunt Bob the Director
Note that Alice does not appear in the left-hand column, because she has no manager, and Charlie doesn't appear in the right-hand column, because he doesn't manage anyone.If we want to list all employees, with their managers where they have them, we can use a left outer join, which returns all rows on the "left" side of the join regardless of whether they have matching rows on the "right" side -- like this (cutting out bits of the query repeated from the previous example):
SELECT ... LEFT OUTER JOIN EMPLOYEES AS mgr ON ...
That produces this: EMPLOYEE_NAME MANAGER_NAME
------------- -------------
Alice the CEO NULL
Bob the Director Alice the CEO
Charlie the Grunt Bob the Director
If we want to see who (if anyone) every employee manages, we could use a right outer join, which is similar to the previous but takes rows from the "right" side whether or not there are matching rows on the "left": SELECT ... RIGHT OUTER JOIN EMPLOYEES AS mgr ON ...
This produces: EMPLOYEE_NAME MANAGER_NAME
------------- -------------
Bob the Director Alice the CEO
Charlie the Grunt Bob the Director
NULL Charlie the Grunt
(To be honest, this is even more contrived than the previous examples: you can achieve the same result by reordering things in the left outer join, and that would come more naturally to most people, including me. And you would probably swap the order you display the columns in. But I include it for completeness.)Finally, you can get a combined list of employees and their managers (if any), and potential managers and their direct reports (if any), with a full outer join, which returns rows from both sides of the join, regardless of whether they have matching rows on the other:
SELECT ... FULL OUTER JOIN EMPLOYEES AS mgr ON ...
Producing: EMPLOYEE_NAME MANAGER_NAME
------------- -------------
Alice the CEO NULL
Bob the Director Alice the CEO
Charlie the Grunt Bob the Director
NULL Charlie the Grunt
Using a left join exclusively isn't a problem, as long as it's returning the data you need. If you use a left join where your data requirements actually call for a different type of join (e.g. "exclude any employees without a manager"), it could be a problem. You could get round it by adding a WHERE clause (e.g. "WHERE mgr.EMPLOYEE_ID IS NOT NULL"), but that's a bit ugly and hacky.https://stackoverflow.com/questions/3183669/difference-betwe...
Let’s say you do an inner join in insert into … select statement to find some other entity which 100% should be there. If something else is screwed up you might silently filtering out rows. With left join you keep everything, but not null constraint on the table protects you and turns it into an explicit error.
Left joins (or right joins, but that sounds like the opposite of the way I see tables in my head) are the most useful in day to day life.
I don't think I ever shipped a crossjoin for perf reasons and very rarely I needed the intersection of two tables.
Most likely the op never was in a situation to need those.
Could we speculate as to what his real name might be? Lefty? Joinathon?
> Lefty? Joinathon?
Samuel Quentin Lucas?(If so, then bug, not feature; at multiple levels: I suspect sadly intentional.)
-1 continue with google
-2 continue with facebook
-3 login
-4 sign up with email
-5 close and read quora
"close and read quora" does not show me the comments...
When you say 'where left join column = some value' you exclude all rows containing NULL in that column. In other words all rows that did not join in addition to rows which contain a NULL in the column.
I've met brilliant people with idiosyncrasies, so I'd chalk it up to a consistency/single-point-of-variance choice where only the WHERE clauses sets the join-type. I'd be curious to know if the clauses that change the join type always came first.
My pet peeve is writing LEFT OUTER JOIN, there's no such thing as a LEFT INNER JOIN so it's just noise--please stop.
I worked with a ‘senior developer’ who, on a really big project with lots of different coders around the country, prototyped the implementation in prolog including the JUnit tests (in prolog too).
I think I actually know the answer to this one. I don't remember whether it was while I was still in school or later, but once heard someone say that they always picked a language to implement a prototype in that would never under any circumstances be used for the final system so that it was impossible to try to hack the prototype into the final system.
And for the record I actually like Prolog for certain projects.
Then we have CROSS APPLY, which I've used once or twice. And finally CTEs which I use a lot, in addition to widow functions.
I think this is known as an INNER JOIN? I dunno, I came from science where cross product and filtering are approached in a very different way.
The "advanced" part is:
1) Set Theory - really understanding set theory so you can model datasets appropriately and write efficient SQL 2) The Toolkit - knowing how the major concepts of SQL (join types, CTEs, table valued functions, windowing, aggregation, conditional logic, indexes, constraints, normalization/denormalization, etc.) contribute to #1 3) Performance Analysis - understanding how to analyze the performance characteristics of a query so you can apply #2 to #1 to achieve good results
And usually the difference I see between juniors and seniors is if you give them 2 "advanced" queries and tell them one runs fine and one doesn't, seniors very quickly know which one is bad and why it runs bad ... juniors aren't even confident the two queries will run because they contain syntax or patterns they're unfamiliar with.
Some systems generate really long SQL queries; I'm thinking of you, Drupal! I haven't worked with D8, and only a little with D7. But D6 would routinely produce SELECT queries with 20 tables joined.
Drupal is notorious for caching nearly everything, including the results of SQL queries, because those queries were essentially untunable (and the "cache" was usually yet another database table). "Flush all of the caches" was the first advice to anyone struggling with a D6 issue.
As a contractor, I was once asked to improve the performance of a query that had a main table with many millions of rows. EXPLAIN PLAN revealed that the query planner was making some bad choices, despite the table statistics being up-to-date. I bullied[0] the optimiser into making some better choices, and got a 100x performance improvement. For large databases, the query plan can make the difference between a query taking a second and taking an hour.
Unfortunately the format of query-plan output from EXPLAIN PLAN is unstandardised and vendor-dependent.
[0] "bullied": This was Oracle; you could use "hints" to force the optimiser to change it's behaviour. If you don't have hints, then sometimes transforming a JOIN query into a query using an inner SELECT will expand the optimiser's consciousness. It all gets a bit voodoo, if the optimiser is stubborn and you don't have hints.
I think it's not necessarily wrong to write a line of code that is never reached, especially for code that may be changed later, and maybe by someone else, which is really all code ever.
You might write the no-op or unreachable else branch just so that the placeholder is there, to highlight that it needs to be considered in case the original condition is ever changed.
It's only unreachable today with todays condition and maybe even just todays data or maybe even just todays version of the language. Tomorrow another programmer could change the if condition, or the data could start to fall through that condition, or even some implicit behaviour of the language could change which ends up changing how the condition is evaluated.
raise Exception("This should never happen")
and feel no need to apologize for it.But how can you be a DBA and not use full outer join or cross join?
Its also true that unless your work is DE or BI analyst, I guess people are not using SQL up to that point.
I've rarely had to use a full outer join; I think that if you encounter that need, it bespeaks a problem with your schema. But sometimes DBAs are extremely resistant to schema changes in production, so you have to work with the schema you have.
FWIW, SQL isn't the core of my trade; I'm not a data analyst, I'm just a normal dev with SQL as one of the things in my toolkit.
For full outer join, well you need to create dim tables sometimes half ad-hoc and full outer seems to be much faster solution than UNION
A senior is an old person, which is (usually) not the same at all as a senior developer.