<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Greg Zemskov</title><author><name>Greg Zemskov</name></author><id>https://teletype.in/atom/gregzem</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/gregzem?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@gregzem?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=gregzem"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/gregzem?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-15T14:32:02.989Z</updated><entry><id>gregzem:bYz3Bw1Wwuk</id><link rel="alternate" type="text/html" href="https://teletype.in/@gregzem/bYz3Bw1Wwuk?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=gregzem"></link><title>SQL: Сравниваем значения на временном интервале</title><published>2021-06-23T15:18:53.118Z</published><updated>2021-06-23T15:18:53.118Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://teletype.in/files/4c/ef/4cef253d-dc2f-4868-b833-eab2819030c1.png"></media:thumbnail><summary type="html">&lt;img src=&quot;https://teletype.in/files/a8/14/a814ee86-c70f-4be7-b3da-5ac781fc39e9.png&quot;&gt;Довольно часто при анализе данных требуется сравнить значения с предыдущими на некотором интервале. Например, сравнить динамику посещений сайта по дням по сравнению с тем, что было год назад. (То есть мы сравниваем значения 22-07-2021 и 22-07-2020, 23-07-2021 и 23-07-2020 и т.д.) Или сравнить прибыль по дням в текущем и прошлом месяцах. Или среднюю нагрузку сайта по часам в будни и в выходные. В общем, применений - масса, пользы - достаточно. 
Данные выбираются достаточно несложным JOIN'ом, но чтобы вам не тратить время, приведу его готовый в виде шаблона с плейсхолдерами. </summary><content type="html">
  &lt;p&gt;Довольно часто при анализе данных требуется сравнить значения с предыдущими на некотором интервале. Например, сравнить динамику посещений сайта по дням по сравнению с тем, что было год назад. (То есть мы сравниваем значения 22-07-2021 и 22-07-2020, 23-07-2021 и 23-07-2020 и т.д.) Или сравнить прибыль по дням в текущем и прошлом месяцах. Или среднюю нагрузку сайта по часам в будни и в выходные. В общем, применений - масса, пользы - достаточно. &lt;br /&gt;Данные выбираются достаточно несложным JOIN&amp;#x27;ом, но чтобы вам не тратить время, приведу его готовый в виде шаблона с плейсхолдерами. &lt;/p&gt;
  &lt;p&gt;Для Clickhouse:&lt;/p&gt;
  &lt;pre&gt;SELECT
  date_sub(YEAR, 1, toDate( {{dt}} )) as prev_{{dt}},
  toDate( {{dt}} ) as cur_{{dt}},
  prev_{{value}},
  {{value}} as cur_{{value}},
  {{value}} - prev_{{value}} as diff_{{value}}
FROM
  {{table}}
  JOIN (
    SELECT
      toDate( {{dt}} ) as another_{{dt}},
      {{value}} as prev_{{value}}
    FROM
      {{table}}
    WHERE toDate( {{dt}} ) &amp;gt;= &amp;#x27;2020-01-01&amp;#x27; and toDate( {{dt}} ) &amp;lt; &amp;#x27;2021-01-01&amp;#x27;
  ) t2
  ON toDate(prev_{{dt}}) = another_{{dt}}&lt;/pre&gt;
  &lt;p&gt;Для SQLite3:&lt;/p&gt;
  &lt;pre&gt;SELECT
  strftime(&amp;quot;%d-%m&amp;quot;, {{dt}}) as cmp_{{dt}}, 
  date({{dt}}, &amp;#x27;-12 month&amp;#x27;) as prev_{{dt}},
  prev_{{value}},
  {{value}},
  {{value}} - prev_{{value}} as diff_{{value}}
FROM
  {{table}} t1
  JOIN (
    SELECT
      {{dt}} as another_{{dt}},
      {{value}} as prev_{{value}}
    FROM
      {{table}}
    WHERE toDate( {{dt}} ) &amp;gt;= &amp;#x27;2020-01-01&amp;#x27; and toDate( {{dt}} ) &amp;lt; &amp;#x27;2021-01-01&amp;#x27;
  ) t2
  ON prev_{{dt}} = another_{{dt}}
	&lt;/pre&gt;
  &lt;p&gt;Замените &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;&lt;strong&gt;{{dt}}&lt;/strong&gt; на имя поля, содержащее дату&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;{{value}}&lt;/strong&gt; на имя поля, содержащее значение, для которого мы выполняем сравнение&lt;/li&gt;
    &lt;li&gt;&lt;strong&gt;{{table}}&lt;/strong&gt; на имя таблицы, откуда тянем данные&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;По сути, у запроса есть два параметра:&lt;br /&gt;1. анализируемый интервал, за который мы смотрим разницу в значениях&lt;br /&gt;2. диапазон дат, в рамках которого мы смотрим значения&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;#1&lt;/strong&gt; задается функцией &lt;strong&gt;date_sub(YEAR, 1, toDate( {{dt}} ))&lt;/strong&gt; для Clickhouse и &lt;strong&gt;date({{dt}}, &amp;#x27;-12 month&amp;#x27;)&lt;/strong&gt; для SQLite.&lt;br /&gt;Здесь можно указать, разницу между анализируемыми датами. Например, чтобы сравнить значения в интервале 1 месяца, нужно поменять параметры этих функций на &lt;strong&gt;date_sub(MONTH, 1, toDate( {{dt}} ))&lt;/strong&gt; и &lt;strong&gt;date({{dt}}, &amp;#x27;-1 month&amp;#x27;) &lt;/strong&gt;соответственно.&lt;/p&gt;
  &lt;p&gt;&lt;strong&gt;#2&lt;/strong&gt; задается условием &lt;strong&gt;WHERE toDate( {{dt}} ) &amp;gt;= &amp;#x27;2020-01-01&amp;#x27; and toDate( {{dt}} ) &amp;lt; &amp;#x27;2021-01-01&amp;#x27;&lt;/strong&gt;. Просто поменяйте интервал (это интервал предыдущего диапазона).&lt;/p&gt;
  &lt;p&gt;И еще, чтобы на графике все выглядело &amp;quot;комильфо&amp;quot;, можно первым параметром сделать вывод значения, которое будет общим для интервалов. Например, если мы сравниваем по дням, то в SELECT для SQLite мы добавим &lt;strong&gt;strftime(&amp;quot;%d-%m&amp;quot;, {{dt}}) as cmp_{{dt}}&lt;/strong&gt;, то есть будет выводится день и месяц (а год у нас отбрасывается, потому что мы сравниваем по годам).&lt;/p&gt;
  &lt;p&gt;Пример того, как оно может выглядеть:&lt;br /&gt;&lt;/p&gt;
  &lt;figure class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://teletype.in/files/a8/14/a814ee86-c70f-4be7-b3da-5ac781fc39e9.png&quot; width=&quot;1920&quot; /&gt;
  &lt;/figure&gt;

</content></entry></feed>