tags:

views:

1619

answers:

21
+6  Q: 

Worst SQL Ever

What is the worst SQL query you've ever seen? What made it bad?

+3  A: 

select * from *

Real bad.

Otávio Décio
SELECT * FROM * WHERE * = '%%'; i dont dare to check if this actually works.
Ólafur Waage
or any cross join between two or more reasonably big tables.
Otávio Décio
cross joining between two large but narrow tables is often an optimal solution for matching sets for example - many-to-many is a common problem
annakata
+16  A: 

The classic xkcd of course:

WHERE name = ROBERT'); DROP TABLE students;--
Doug T.
Why did you get negative votes for this? It is hilarious!
some
Oh, someone removed their negative vote.
some
We call him Little Bobby Tables
TrickyNixon
How is this considered "worst"? It is brilliant.
icelava
The greatness is not the query, it's the name :)
biozinc
+8  A: 

A customer was storing a comma delimited list of 3 values in a varchar field (classic ASP application) so they had a stored procedure that looked something like this:

SELECT *
FROM
    SomeTable
WHERE
    Field LIKE @Param + ',%'
    OR
    Field LIKE '%,' + @Param + ',%'
    OR
    Field LIKE '%,' + @Param

It should be obvious why it's horrible :)

Sean Bright
ouch! That makes my teeth hurt!
Mitch Wheat
I have seen similar things in a large production program :S
Ólafur Waage
Is there a better way to write this?
Alterlife
</clueless> :)
Alterlife
Don't know if better is the right word but -- WHERE ',' + Field + ',' LIKE '%,' + @Param + ',%' -- will probably run faster. Of course you shouldn't have comma delimited data inside fields in a RDBMS.
jmucchiello
+2  A: 

Recently, I've seen a (greater than) 4000 line TSQL stored procedure that was a chain of IF statments for matching parts of addresses. It could be reduced to less than 50 lines!

I'm saving the code for a future DailyWTF!

Mitch Wheat
+2  A: 
SELECT * FROM some_table;

What made it so bad was the code was relying on getting the results in order based on a timestamp. This had apparently worked for a while before I got called in to fix it.

Jeremy Wilde
+21  A: 
DELETE FROM table

Seen right after I typed and executed it, I had forgotten the WHERE clause. Now I always run a SELECT statement first and change the SELECT to DELETE after I am satisfied that the proper rows will be affected.

Robert Gamble
Ouch..! I'm paranoid, I always surround update/delete statements with begin tran/rollback, try it and then execute the inner part when I feel safe.
Otávio Décio
I do something similar, except I just write TableName as TableNameFOO while I am authoring it. I also keep the "To:" field of e-mails empty before I write the entire e-mail and proofread... just in case ;)
Sean Bright
@ocdecio: This was MySQL, before they supported transactions :(
Robert Gamble
@sean: I have a colleague that starts DELETE statements with WHERE 1=0 just in case they forget to add the correct WHERE clause before they hit the execute button. Also, I do the same thing with emails.
Robert Gamble
ditto, and i am amazed how often, i get a different result set than expected.
EvilTeach
Guys... select * into z_backup from <important table> as your first step. Then go hog wild.
Robert C. Barth
I've done this before whilst at work, fortunately I was working on the development server and I just restored the last working database backup. I also wrote a web page for managing educational status for employees recently and left out the where clause. Let's just say everyone has a degree now.
Kezzer
haha. I always start with BEGIN on production.
Arthur Thomas
And this is why I believe that DELETEs and INSERTs should require the programmer to express his intent explicitly to apply the statement to all of the rows, e.g. DELETE ALL FROM table
DrJokepu
Ouch. I felt that pain myself. Once.
Christian Nunciato
Happened to me once with the same result - I always select first now and then change the query when satisfied with the results.
Mark Brittingham
+4  A: 
select * from users where clue > 0;
0 results found.
Paul Tomblin
the worst thing about this sql is that it never returns any results, no matter where you run it
Steven A. Lowe
This is why we should be able to upvote comments :)
Robert Gamble
What happens why you run this query on the Stack Overflow database? Does it still return 0 results? Or does it just return user ID 22656
Kibbee
Why is this bad SQL? Why play shoot-the-messenger?
Loren Pechtel
I have that t-shirt.
chaos
+3  A: 

It's probably not the worst but I see this far too often (Misuse of the group by clause):

SELECT
  C.CustomerID, C.CustomerName, C.CustomerType, C.Address1, C.City,   
  C.State, SUM(S.Sales) as TotalSales
FROM
  Customers C
INNER JOIN Sales S
  ON C.CustomerID = S.CustomerID
GROUP BY
  C.CustomerID, C.CustomerName, C.CustomerType, C.Address1, C.City, C.State

Instead of:

SELECT
  C.CustomerID, C.CustomerName,
  C.CustomerType, C.Address1, C.City,
  C.State, S.TotalSales
FROM
  Customers C
INNER JOIN
  (SELECT CustomerID, SUM(Sales) as TotalSales FROM Sales GROUP BY CustomerID) S
ON
  C.CustomerID = S.CustomerID
Corin
call me out on this is you will but I disagree that as a rule that 1 is bad and 2 is good. With a more complex example, 2 becomes quite a bit harder to maintain. To me, 1 is very clear in its intent and therefor, simpler to maintain. 2 can offer better performance but the gain may not be worth it.
TrickyNixon
Also, rule 2 is slower under mysql. mysql--. the latter is even more maintainable if you disassemble it and use string-substitution to compose the final query. INNER JOIN ( $customerTotals ) :D
Kent Fredric
Will there not be an extra join with syntax 2? May or may not matter
erikkallen
+1 for the interesting refactoring - good point. Version 1 is a simple pre-SQL-92 query adapted to use the SQL-92 join notation. The second shouldn't be slower - it does the grouping on a single table and then joins that with the original (unless, I suppose, the optimizer doesn't order the sub-query result and exploit that order in merge join with the customer table, in which case it might be slower than an indexed join).
Jonathan Leffler
+4  A: 

My own, which is far to long to post here -- closing now on 3500 lines

I have to really share the blame with an absolutely horrible schema. What started off as a simple exercise in pivoting denormalized data using some unions turned into an unwieldy nightmare. It's badly in need of repair.

Runner up is this:

select 
case datepart(mm,getdate())
when 1 then 'Jan'
when 2 then 'Feb'
when 3 then 'March'
when 4 then 'Apr'
when 5 then 'May'
when 6 then 'Jun'
when 7 then 'July'
when 8 then 'Aug'
when 9 then 'Sept'
when 10 then 'Otc'
when 11 then 'Nov'
when 11 then 'Dec'
end

There are no typos in that post -- that's how it was written. Thank you, consulting dollars!

I of course refactored with Select left(datename(mm, getdate()), 3)

TrickyNixon
11 mapped both to Nov and Dec?? Really?
abelenky
We discovered this gem in December.
TrickyNixon
In a workplace that will remain nameless, your fix would actually be frowned upon because it breaks the spelling for "Sept" and "March" (never-mind that it fixes a bug).
dreftymac
Spelling error for Oct...
Shivasubramanian A
@Shivasubramanian: Yes - there was a spelling error in Otc; that is one of the points.
Jonathan Leffler
@TrickyNixon: the advantage of that solution is that it is not affected by locale - so even the French, Spanish, German or Japanese users get forced to use the English abbreviations for the month names. :D
Jonathan Leffler
@Jonathan, aargh!! Thanks for pointing that out... ;-)
Shivasubramanian A
<sarcasm>Doesn't everyone speak American English? Bah!</sarcasm>
James Schek
Jonathan Leffler: This is also a disadvantage. It is quite possible that there is a language out there where two months share the same first 3 letters.
DrJokepu
A: 

read it out loud.

select [select],*,star as [as] from [from],[order] order by [by]

Is that supposed to be something like http://slashdot.org
Kibbee
+5  A: 

When I first got my current job my first project was to create an application that summarized our license usage data in our computer labs. He insisted that he didn't want the backend database to be normalized because joins were "too expensive." It being my first week, I wasn't in a position to argue.

Now, in order to extract any useful data from the database, one has to "undo" the denormalization in every query that needs to extract summaries to remove the duplicated data in each row. Of course, these are the only queries that are actually used. You see a lot of nested selects that would be completely unnecessary if the data were normalized, such as:

select location, sum(login_time) as total_login_time
from
    (select location, session_id, max(login_time) as login_time
     from sessions
     where location in ('lab1','lab2') 
           and session_start >= @start_date 
           and session_end <= @end_date
     group by location, session_id) tbl
group by location

Although, the query itself isn't particularly ugly -- though some are -- the process of having to jump through hoops every time to undo the unnecessary denormalization hurts.

Now the boss is gone, but I don't have time to rewrite it...

tvanfosson
make some views to denormalise the data for you :D
Kent Fredric
This is just wrong on so many levels. Especially the comment about joins being "too expensive."
Mark Brittingham
+1  A: 

DELETE FROM some_table WHERE some_thing IN (SELECT some_column_from_wrong_table FROM correct_table WHERE some_id=something).

The some_column_from_wrong_table has a column that wasn't even in the table, but it was in another table. Problem was the correct_table was named 'Event' and somehow it returned ALL rows instead of NO rows (or more importantly, an error!).

Two lessons learned: NEVER EVER, under any circumstances, name a table after any form of system name. Second thing was run select statements first, then change to delete.

This was SqlServer 2005 by the way. I'm still pissed it didn't throw an error.

Nazadus
+2  A: 

In an Access Database, there was a query like the following:

SELECT *
FROM Bad_2 INNER JOIN Bad_1 ON Bad_2.Bad_1_id = Bad_1.ID;

and both tables had a field with the same name. When Access comes across a field name for a second time, it makes up a new name for it. The previous guy used the generated field name in code.

jrcs3
+1  A: 

Seen many woeful pieces of SQL in my time. One that comes to mind is of the form

load data from a file, loop over that file, accessing db for each line in file.

Seems ok on test systems with 10 or so lines, 100K-1million = nasty even for primary key lookups.

BTW, the solution is to load the data into the db and think in sets.

-- Choose your favourite lang eg. perl, python ...

load file into data structure (eg array)

for (1 .. n) loop
myid := array[n];
select * from table where id = myid;
if the row exists update table set ... where id = myid;
end loop;

+9  A: 

Worst USE of an SQL query every:

A SELECT query that that counts the number of lines corresponding to a certain condition, called in the stopping condition of a for loop.
Something like this:

for(int i = 0; i < query("SELECT COUNT .... WHERE ..."); i++)
{

}

And no, the result of the query doesn't change every iteration. Yes I realize the server is going to cache the result.

shoosh
+3  A: 

In a posting to the comp.databases.informix news group - a genuine working Informix table (which I do not recommend using):

CREATE TABLE VIEW
(
    DECIMAL     CHAR(30),
    NOT         INTEGER NOT NULL,
    SERIAL      DATE NOT NULL,
    NULL        CHAR(1) NOT NULL,
    INTEGER     DECIMAL(13,6) NOT NULL
);

It helps (marginally) if you know that SERIAL is a type in Informix databases - basically, one of the types for generating automatically allocated numbers serially.

Jonathan Leffler
+1  A: 

I liked the one reposted recently on the dailywtf, the story that comes with it is wonderful as well.

Matt
+4  A: 

A PL/SQL (Oracle) stored proc that sorted a result set using a Bubble Sort. It was discovered when I and the DBA were asked to figure out a severe performance problem. The developer, an Oracle "expert," had worked on it for over a week. He explained with a straight face that he learned about Bubble Sort in his computer science class. The algorithm is commonly used to illustrate poor performance.

Replaced the whole mess with an ORDER BY clause. Performance improved by several orders of magnitude.

gregjor
There may be some Oracle consultants who aren't unbearably bad but I've never met one. I worked with one group whose Oracle "expert" had written an entire accounting program using "Bat" files tied to keys. Thus, "I.bat" ran an Invoice form, "R.bat" ran reports. Yes, this was in the late 90s.
Mark Brittingham
+1  A: 

I think this is the worst (especially followed by a painful and null rollback):

DROP DATABASE;
ROLLBACK;
FerranB
+3  A: 

SUBSTRING( (SUBSTRING(LastName, 0, CHARINDEX(' ', LastName)) + ', ' + FirstName), 0, CHARINDEX(' ', (SUBSTRING(LastName, 0, CHARINDEX(' ', LastName)) + ', ' + FirstName), LEN(LastName) + 3) )

they apparently weren't familiar with RTRIM;

RTRIM(LastName) + ', ' + RTRIM(FirstName)

Anthony
A: 
SELECT name FROM categories WHERE id IN (".implode(",",corrected_cats($ad->id)).") ORDER BY name ASC

Yes, you're reading that right... comma separated fields in a field.

gms8994