Даты и текст в SQL: strftime и склейка строк
Время и текст выглядят простыми полями — и именно поэтому на них чаще всего спотыкаются. У даты в SQLite нет собственного типа: она хранится как обычный текст, и сравнивать её можно, только если формат у всех строк одинаковый.
Извлечь часть даты — отдельная функция, и она возвращает не число, а строку.
SELECT strftime('%Y', date) AS год
FROM receipts;
-- результат — текст '1983', не число 1983«Дата тут не дата. Дата тут — аккуратно оформленный текст, который ведёт себя как дата, пока вы не попробуете с ней что-то посчитать.»
Что происходит, когда имя склеивают из двух граф?
Вторая половина урока — склейка строк. || сцепляет текст, стандартно и везде одинаково по смыслу — но с характером.
SELECT first || ' ' || last AS имя
FROM contacts;Капкан: || заразителен. Если хоть один кусок в цепочке — призрак (пустая графа), заражается вся строка целиком, а не только этот кусок.
SELECT first || ' ' || last AS имя
FROM contacts;
-- last IS NULL → имя целиком пропадает, а не 'Клара 'Лечится тем же, чем и в прошлом уроке — COALESCE перед склейкой затыкает призрака заранее.
SELECT first || ' ' || COALESCE(last, '') AS имя
FROM contacts;Почему тот же запрос на другом движке отвечает иначе?
И дальше — сама причина заголовка. На одном движке || значит «склеить», на другом — «логическое ИЛИ». Один и тот же символ, разный смысл, и никто не предупредит вас об этом при переносе запроса.
«„Работало у меня“ — потому что архив был другой. Даты и строки переносятся между движками хуже всего остального в этом ремесле.»
На работе так ловят отчёты по периодам и склеенные имена/адреса, которые молча теряют половину строки. Дата и текст простые только на первый взгляд.
Даты и склеенные имена — половина улик в архиве. Не верьте им на слово, проверьте на живом деле.