Рубрики
blogpost Без рубрики

О работе с процентами

Сегодня ехал в метро и на экране, призванном нести свет знаний, увидел интересный факт:

Во время отдыха летучие мыши неподвижны и понижают температуру тела на 94 процента

Осознать, что именно значит эта формулировка я так и не смог. Допустим, была у мыши температура +30 градусов по шкале Цельсия. Получается, во время отдыха летучая мышь остынет примерно до двух градусов, став природным холодильником? А если на улице в это время +25, то такая температура становится просто неправдоподобной!

Немного почитав, я выяснил, что на самом деле, во время отдыха летучая мышь действительно остывает, иногда почти до температуры окружающей среды. Но откуда взялось 94% я так и не понял. Думаю, даже сами авторы этого «факта» не смогут объяснить, что именно они имели в виду.

Рубрики
blogpost Без рубрики

Музыкальные шкатулки

Когда-то давно мне подарили чай в музыкальной шкатулке. Я сначала думал, что музыка там играется через простенький динамик, по крайней мере именно так были устроены музыкальные открытки.

Сегодня чай закончился и я, разобрав коробку, с удивлением обнаружил там простое механическое устройство. Пружина крутит барабан на который нанесены выступы. Эти выступы при вращении барабана задевают металлические пластинки, которые, собственно, и издают звук.

Википедия утверждает, что примерно так работают всем известные шарманки и даже куранты. Также из википедии я узнал, что изначально шарманки использовались для обучения певчих птиц, а слова «куранты» и «прейскурант» родственные.

Рубрики
blogpost Без рубрики

Что на самом деле значит фраза «вероятность дождя 20%»

Вы никогда не задумывались, что метеорологи вкладывают в формулировку вероятность дождя 20%? Любой человек, изучавший тервер, понимает, что это единичное событие, и говорить о его вероятности просто некорректно.

Да и как в принципе эти 20% понимать? Это значит, что в условной Москве только 20% территории будет мокнуть? Или дождь будет иди 20% дня?

На самом деле всё довольно просто. Так как у метеорологов нет абсолютно точных исходных данных для вычисления прогноза погоды, они проводят не одну симуляцию, а некоторое их множество, каждый раз чуть изменяя начальные значения температуры, влажности, давления и др. Вероятность дождя 20% означает, что именно такая доля симуляций предсказала дождь. Не знаю, будет ли вам полезно это знание, но одной тайной стало меньше.

Рубрики
Без рубрики

Кристалл висмута (Bi)

При нормальных условиях висмут блестящий серебристый металл с розоватым оттенком. Но синтезированный кристалл (на фото) покрыт оксидной плёнкой, которая и придаёт радужный цвет.

Из интересных особенностей висмута можно отметить то, что при плавлении его плотность увеличивается, т.е. в кристаллической форме он занимает на 3.3% больший объём, чем жидкой форме. Такое поведение характерно для весьма небольшого количества веществ. В повседневной жизни вы могли такое замечать у обычной воды.

Рубрики
sql Без рубрики

Нахождение последней записи

Я по работе часто сталкиваюсь с ситуацией, когда нужно восстановить состояние таблицы на какой-то момент в прошлом. Мне всегда казалось, что это довольно простая и очевидная задача, но несколько дней назад я всерьёз над ней задумался и пришёл к выводу, что не всё так очевидно. Мы рассмотрим эту задачу на примере таблицы с отправленными SMS. Мы хотим узнать какого типа было последнее сообщение отправленное на каждый номер.

IDPhoneSMSType
Уникальный монотонно возрастающий идентификатор SMS.Номер телефона на который отправлено сообщениеТип сообщения

Первое решение, которое пришло мне в голову — использовать cross apply, чтобы для каждого уникального номера телефона подзапросом найти соответствующий тип:

;WITH [cte] 
     AS (SELECT [S].[phone] 
         FROM   [dbo].[smslog] AS [S] 
         GROUP  BY [S].[phone]) 
SELECT [ca].[id], 
       [cte].[phone], 
       [ca].[smstype] 
FROM   [cte] 
       CROSS apply (SELECT TOP 1 [ca_s].[id], 
                                 [ca_s].[smstype] 
                    FROM   [dbo].[smslog] AS [ca_s] 
                    WHERE  ( 1 = 1 ) 
                           AND ( [ca_s].[phone] = [cte].[phone] ) 
                    ORDER  BY [ca_s].[id] DESC) AS [ca] 

Довольно очевидным шагом является избавление от CROSS APPLY и замена его на JOIN:

;WITH [cte] 
     AS (SELECT [S].[phone], 
                Max ([S].[id]) AS ‘maxID’ 
         FROM   [dbo].[smslog] AS [S] 
         GROUP  BY [S].[phone]) 
SELECT [S].[id], 
       [S].[phone], 
       [S].[smstype], 
       [cte].[phone], 
       [cte].[maxid] 
FROM   [dbo].[smslog] AS [S] 
       INNER JOIN [cte] 
               ON ( 1 = 1 ) 
                  AND ( [S].[id] = [cte].[maxid] ) 

Даже без использования индексов второй вариант гораздо быстрее. Но, оказывается, есть ещё интересный вариант, который позволяет вообще избежать соединений. Для этого нам придётся прибегнуть к оконной функции:

;WITH [cte] 
     AS (SELECT [S].[id], 
                [S].[phone], 
                [S].[smstype], 
                Row_number () 
                  OVER ( 
                    partition BY [S].[phone] 
                    ORDER BY [S].[id] DESC ) AS ‘rn’ 
         FROM   [dbo].[smslog] AS [S]) 
SELECT [cte].[id], 
       [cte].[phone], 
       [cte].[smstype] 
FROM   [cte] 
WHERE  ( 1 = 1 ) 
       AND ( [cte].[rn] = 1 ) 

Все представленные выше планы запросов получены, когда на таблице нет никаких индексов, но важно понимать, что их добавление может значительно изменить план. Например, после добавления некластеризованного индекса по полям (Phone;ID) и включённым полем smstype в третьем запросе вообще исчезает этап сортировки, а время тратится практически исключительно на просмотр индекса.

Рубрики
blogpost Без рубрики

FaceID и коронавирус

Лично для меня самое большое неудобство, связанное с коронавирусом, — необходимость носить маску. И если к запотевающим очкам и ощущению маски на лице привыкнуть ещё можно, то к неработающему FaceID нельзя.

Рубрики
blogpost Без рубрики

Предположение — мать всех ошибок

Когда-то давно я услышал фразу, вынесенную в заголовок. С тех пор я постоянно убеждаюсь в её истинности. Сегодня мне почему-то вспомнился тот самый короткий рассказ, способный растрогать любого.

«For sale, baby shoes, never worn» («Продаются детские ботиночки. Неношеные»)

Негласно подразумевается, что ботиночки не пригодились, потому что с ребёнком что-то случилось. Но, если задуматься, причин может быть множество: например, ребёнку не понравился цвет, обувь оказалась не по размеру, погода не позволила носить эту обувь, да даже просто молодые родители могли не угадать пол ребёнка, когда покупали ботинки.

По большому счёту в самом рассказе нет ничего такого, что должно растрогать читателя. В отсутствие деталей мы вынуждены делать предположение, которое, как известно, ведёт к ошибкам.

Рубрики
blogpost sql Без рубрики

О важности первичных ключей

Сегодня ходил со своей девушкой на один концерт. Непосредственно перед началом выяснилось, что все билеты каким-то образом оказались проданы дважды. Если это не лучшая иллюстрация важности первичных ключей в базе, то что?

Рубрики
blogpost Без рубрики

Порядок против здравого смысла

Я очень люблю фотографировать всё подряд. Во время путешествий я чаще смотрю на мир через экран фотоаппарата, а не своими глазами.

Тысячи полученных фотографий нуждаются в сортировке. Я стараюсь не ограничиваться альбомами и к каждой фотографии добавляю теги, чтобы потом было проще найти нужный объект. Но вот недавно моя любовь к точным тегам привела к том, что фотографии стало искать сложнее.

Помимо экспонатов в музеях или городских видов у меня есть сотни фотографий жителей моих аквариумов. Раньше они были подписаны торговыми названиями, но я решил, что нужно использовать видовые названия на латыни. Теперь моя коллекция подписана как в том анекдоте про математика «абсолютно точно, но абсолютно бесполезно».