I enjoyed the David Fincher remake of The Girl With The Dragon Tattoo more than I thought I would. Rather than a shallow and cynical Hollywood cash-in, it's actually a tense, atmospheric, only slightly voyeuristic crime thriller. My favourite part, though, was when Lisbeth Salander begins to solve a 40 year old murder cold case using SQL.
We see her tapping at her laptop as she hacks effortlessly into the Swedish police database, interspersed with green-tinted tracking shots of scrolling text as she types in keywords like 'unsolved' and 'decapitation', though never quite the whole query:
Naturally I couldn't help stitching a few screenshots together in Photoshop, and this is what I got:
![[Girl-with-the-ANSI-Tatoo-SQL.jpg]](http://www.williamrobertson.net/images/Girl-with-the-ANSI-Tatoo-SQL.jpg)
Immediately moviegoers will notice that this can't be Oracle SQL - obviously the AS keyword is not valid for table aliases. In fact as we pull back for a thrilling query results listing we see the mysql prompt and giveaway use [dbname] connect syntax and over-elaborate box drawing.
Notice we can just make out the 'FT' of an ANSI left join to the Keyword table.
Finally we get a full-screen shot of the results listing for Västra Götaland:
Here's what we were able to reconstruct in the Oracle WTF Forensics department:
SELECT DISTINCT v.fname, v.lname, i.year, i.location, i.report_file
FROM Incident AS i
LEFT JOIN Victim AS v on v.incident_id = i.id
LEFT JOIN Keyword AS k ON k.incident_id = i.id
WHERE i.year BETWEEN 1947 AND 1966
AND i.type = 'HOMICIDE'
AND v.sex = 'F'
AND i.status = 'UNSOLVED'
AND ...
OR v.fname IN ('Mari', 'Magda')
OR SUBSTR ...
AND (k.keyword IN ('rape', 'decapitation', 'dismemberment', 'fire', 'altar', 'priest', 'prostitute')
...
AND SUBSTR(v.fname, 1, 1) = 'R' AND SUBSTR(v.lname, 1, 1) = 'L');
+--------+---------+------+-----------+----------------------------------+
| fname | lname | year | location | report_file |
+--------+---------+------+-----------+----------------------------------+
| Anna | Wedin | 1956 | Mark | FULL POLICE REPORT NOT DIGITIZED |
| Linda | Janson | 1955 | Mariestad | FULL POLICE REPORT NOT DIGITIZED |
| Simone | Grau | 1958 | Goteborg | FULL POLICE REPORT NOT DIGITIZED |
| Lea | Persson | 1962 | Uddevalla | FULL POLICE REPORT NOT DIGITIZED |
| Kajsa | Severin | 1962 | Dals-Ed | FULL POLICE REPORT NOT DIGITIZED |
+--------+---------+------+-----------+----------------------------------+
Shocked moviegoers will have been left wondering why a genius-level hacker would outer-join to the Victims and Keywords tables only to use literal-text filter predicates that defeat the outer joins, whether MySQL has a LIKE operator, and why none of the victims' initials are 'R L'.