{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "LEFT JOIN: blog on analytics, visualisation & data science, posts tagged: redash",
    "home_page_url": "https:\/\/en.leftjoin.ru\/tags\/redash\/",
    "feed_url": "https:\/\/en.leftjoin.ru\/tags\/redash\/json\/",
    "icon": "https:\/\/en.leftjoin.ru\/user\/userpic@2x.jpg",
    "author": {
        "name": "Nikolay Valiotti",
        "url": "https:\/\/en.leftjoin.ru\/",
        "avatar": "https:\/\/en.leftjoin.ru\/user\/userpic@2x.jpg"
    },
    "items": [
        {
            "id": "60",
            "url": "https:\/\/en.leftjoin.ru\/all\/redash-dashboard-overview\/",
            "title": "Redash Dashboard Overview",
            "content_html": "<p>Redash is an open-source tool that is available in two versions: self-hosted and cloud. If you use the first one, Redash is free of charge, but for a cloud option you’ll have to pay. In both versions you can connect to a numerous amount of databases (including Clickhouse) or other sources like Google Sheets by API.<\/p>\n<p>Redash is a SQL query editor that allows building visualizations. To make a dashboard, we first need to run a SQL query and then build a visualization. After that, we can add the queries with their visualizations to the dashboard. The process makes data investigations easy and simple.<\/p>\n<h2>Data preparation<\/h2>\n<p>To start working with data we need to click settings and create a new data source.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-05-181541.png\" width=\"1237\" height=\"774\" alt=\"\" \/>\n<\/div>\n<p>When working with Superstore dataset we could not directly connect a .xlsx file as redash works only with databases. Thus, we uploaded our .xlsx into a MySQL database.<\/p>\n<h2>Building reports and visualizations<\/h2>\n<p>In the beginning of the dashboard, you can see the filters. This is the only way to apply filters to a dashboard in Redash and to choose parameters like province interactively.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-193757.png\" width=\"1920\" height=\"903\" alt=\"\" \/>\n<\/div>\n<p>First of all, we added KPI cards to the dashboard. The functionality of Redash is extremely limited in terms of visualizations, so the only way to build a KPI card was by using so-called counters. A counter is a type of visualization that allows displaying a current and a target value, however, in our case we used the previous year value instead of the target.<\/p>\n<p>For the KPI cards, we used the query below.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195521.png\" width=\"1431\" height=\"648\" alt=\"\" \/>\n<\/div>\n<p>It’s a simple query that returns the sum of the profit in current month and the sum of the profit in the previous one. In each query we need to define Year and Month and Province in the WHERE statement, so that all our visualizations are filtered based on the chosen year, month and province. The results are two numbers, curr and prev. Then we click on New Visualization, choose counter as a type and assign curr to the counter value and prev to the target value. We can also change format by adding a dollar sign prefix.<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"1867\" data-ratio=\"2.1608796296296\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195956.png\" width=\"1867\" height=\"864\" alt=\"\" \/>\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195719.png\" width=\"1860\" height=\"858\" alt=\"\" \/>\n<\/div>\n<\/div>\n<p>In our previous reviews of BI-tools, we displayed all KPI cards in a single line. In Redash, however, the numbers were too small when displayed in a single line and unnecessary information like the query name and the last update time were cluttering the view. This is another disadvantage of Redash, so we had to make bigger cards and display them in two lines.<\/p>\n<p>To display top performing provinces we used word clouds. The query returned the sum of sales by provinces. Then the sum of sales was used as a frequency column to define the size of the province names.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-202308.png\" width=\"1867\" height=\"862\" alt=\"\" \/>\n<\/div>\n<p>For Profit Dynamics visualization we used a simple line graph. The query below returned a table with total profits for each month as well as two additional columns that display profit in the current month and the previous one.<\/p>\n<pre class=\"e2-text-code\"><code>select date_format(orders.OrderDate, '%Y-%m-01') as month, sum(orders.Profit) as profit, curr.curr_profit, prev.prev_profit\r\nfrom orders\r\nleft join (\r\n    select date_format(OrderDate, '%Y-%m-01') as month, sum(Profit) as curr_profit\r\n    from orders\r\n    where MONTH(OrderDate)=MONTH('{{Year and Month}}') and YEAR(OrderDate)=YEAR('{{Year and Month}}')\r\n        and ('{{Province}}'='0. All' or Province = '{{Province}}')\r\n    group by 1\r\n) curr on curr.month=date_format(orders.OrderDate, '%Y-%m-01')\r\nleft join (\r\n    select date_format(OrderDate, '%Y-%m-01') as month, sum(Profit) as prev_profit\r\n    from orders\r\n    where MONTH(OrderDate)=MONTH('{{Year and Month}}') and YEAR(OrderDate)=YEAR('{{Year and Month}}')-1\r\n        and ('{{Province}}'='0. All' or Province = '{{Province}}')\r\n    group by 1\r\n) prev on prev.month=date_format(orders.OrderDate, '%Y-%m-01')\r\nwhere ('{{Province}}'='0. All' or Province = '{{Province}}')\r\ngroup by 1,3,4\r\norder by 1<\/code><\/pre><p>We then used the a line graph to display the profit column and a scatter plot to display curr_profit and prev_profit columns as both of them had only one observation.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-203727.png\" width=\"1867\" height=\"865\" alt=\"\" \/>\n<\/div>\n<p>Profit and Sales by Category visualization shows a SQL query table that returns profits and sales by category and sub-category of products.<\/p>\n<p>Last but not least, we have pivot tables for top products and top customers by profit. Pivot tables in Redash allow grouping elements by using aggregate functions. In our case we grouped products by profit. I do not recommend using this feature for a large amount of data as if you change the aggregations on the fly in the browser, the browser might slow down and even crash.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-204757.png\" width=\"1870\" height=\"865\" alt=\"\" \/>\n<\/div>\n<h2>Conclusions<\/h2>\n<p>You can find the final dashboard <a href=\"http:\/\/redash.datamarathon.ru\/public\/dashboards\/csdQnKTY5nkvByyFu9gE1DadUlCwyQBEOypaFIBj?org_slug=default&p_Province=0.%20All&p_Year%20and%20Month=2010-05-01\">here<\/a>.<br \/>\nOur team has evaluated the dashboard and the following scores on 1-10 scale 10 being the highest were given:<\/p>\n<ol start=\"1\">\n<li>Meets the tasks – 7.3<\/li>\n<li>Learning curve  – 7.5<\/li>\n<li>Tool functionality – 5.5<\/li>\n<li>Ease of use – 7.5<\/li>\n<li>Compliance with the layout – 6.0<\/li>\n<li>Visual evaluation – 5.2<\/li>\n<\/ol>\n<p>Overall: 6.5 out of 10.<\/p>\n",
            "date_published": "2021-05-07T13:24:27+03:00",
            "date_modified": "2021-05-07T13:24:12+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-192624.png",
            "_date_published_rfc2822": "Fri, 07 May 2021 13:24:27 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "60",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/fotorama\/fotorama.css",
                    "system\/library\/fotorama\/fotorama.js",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-192624.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-05-181541.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-193757.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195521.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195956.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-195719.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-202308.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-203727.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/--2021-05-04-204757.png"
                ]
            }
        },
        {
            "id": "50",
            "url": "https:\/\/en.leftjoin.ru\/all\/calculating-user-retention-by-24-hour-windows\/",
            "title": "Calculating User Retention by 24-hour windows and calendar days in SQL",
            "content_html": "<p>Yesterday I got a message from one of our blog readers, asking:<\/p>\n<blockquote>\n<p><i>Let’s say today’s Monday, and an app was downloaded 187 times. If I want to find out what’s the Retention rate was on day 1, what day of the week should I start taking the count with?<\/i><\/p>\n<\/blockquote>\n<p>He is referring to the blog post on <a href=\"https:\/\/en.leftjoin.ru\/all\/retention-rate\/\">Сalculating Retention Rate<\/a>. I would like to clarify that since retention rate can be calculated by 24-hour windows, as well as by calendar days. In our case, day 0 will be Monday, and day 1 will be Tuesday. However, there is one little hiccup...<\/p>\n<p>For example, if we started promoting our product on Monday, October 12 at 23:59, then all downloads of this day will have the retention rate of day 1. It’s a problem of performing calendar calculations. To address this, some data analysts calculate retention rate not only by calendar days but also by 24-hour windows.<\/p>\n<p>Let’s apply this idea to the above case:<\/p>\n<ul>\n<li>The Retention rate for day 0 can be calculated using the number of downloads from October 5, 23:59 to October 6, 23:59.<\/li>\n<li>The Retention rate for day 1:  from October 6, 23:59 to October 7, 23:59<\/li>\n<li>And so on rolling 24-hour window.<\/li>\n<\/ul>\n<h2>How to calculate Retention Rate by 24-hour windows in SQL?<\/h2>\n<p>Let’s recall one of the queries from our previous post. It was written to calculate the difference between the download date and the user activity date. We need to change the query so that user activity is calculated by 24-hour windows. To accomplish this just change the calculation for <i>datediff<\/i> to 24-hour windows, updating the lines in bold.<\/p>\n<pre class=\"e2-text-code\"><code class=\"SQL\">\r\nSELECT from_unixtime(user.installed_at, \"yyyy-MM-dd\") AS reg_date,\r\n   <b>floor((cast(cs.created_at as int)-cast(installed_at as int))\/(24*3600)) as date_diff,<\/b>\r\n   ndv(user.id) AS ret_base\r\n   FROM USER\r\n   LEFT JOIN client_session cs ON cs.user_id=user.id\r\n   WHERE 1=1\r\n     <b>AND floor((cast(cs.created_at as int)-cast(installed_at as int))\/(24*3600)) between 0 and 30<\/b>\r\n     AND from_unixtime(user.installed_at)>=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)<=date_add(now(), -31)\r\n   GROUP BY 1,2\r\n<\/pre>\n<\/code><p>Updated query:<\/p>\n<pre class=\"e2-text-code\"><code>SELECT \r\n       cohort.date_diff AS day_difference,\r\n       avg(reg.users) AS cohort_size,\r\n       avg(cohort.ret_base) AS retention_base,\r\n       avg(cohort.ret_base)\/avg(reg.users)*100 AS retention_rate\r\nFROM\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          ndv(user.id) AS users\r\n   FROM USER\r\n   WHERE from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1) reg\r\nLEFT JOIN\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n    floor((cast(cs.created_at as int)-cast(installed_at as int))\/(24*3600)) as date_diff,\r\n          ndv(user.id) AS ret_base\r\n   FROM USER\r\n   LEFT JOIN client_session cs ON cs.user_id=user.id\r\n    WHERE 1=1\r\n     AND floor((cast(cs.created_at as int)-cast(installed_at as int))\/(24*3600)) between 0 and 30\r\n     AND from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1,2\r\n  ) cohort ON reg.reg_date=cohort.reg_date\r\n    GROUP BY 1        \r\n    ORDER BY 1<\/code><\/pre><h2>Final output:<\/h2>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/1-19.png\" width=\"1170\" height=\"400\" alt=\"\" \/>\n<\/div>\n<p>Compare it with the previous one:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/2-19.png\" width=\"1170\" height=\"400\" alt=\"\" \/>\n<\/div>\n<p>And as you see, the retention rate calculated using 24-hour windows is slightly lower in the first days.<\/p>\n",
            "date_published": "2020-10-21T15:44:39+03:00",
            "date_modified": "2020-10-21T16:15:27+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/1-19.png",
            "_date_published_rfc2822": "Wed, 21 Oct 2020 15:44:39 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "50",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/1-19.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/2-19.png"
                ]
            }
        },
        {
            "id": "48",
            "url": "https:\/\/en.leftjoin.ru\/all\/guide-to-modern-business-intelligence-tools\/",
            "title": "Guide to modern Business Intelligence Tools",
            "content_html": "<p>In our new series, we will try to give a detailed representation of  several BI tools using the <a href=\"https:\/\/github.com\/PacktPublishing\/Tableau-10-Best-Practices\/blob\/master\/Chapter%205\/Sample%20-%20Superstore%20Sales%20(Excel).xls\">SuperStore Sales dataset<\/a>. The data in SuperStore Sales reflect sales and profit of the retail chain in US dollars.<\/p>\n<p>In the upcoming blog post, we will discuss a real problem statement that could arise when creating a dashboard based on the SuperStore Sales data and design a functional layout to provide clear answers. Throughout this task, we’ll stick with a predefined set of colors to make the comparison more unbiased.<\/p>\n<p>Next, we’re going to create a dashboard that would assist in data-based decision-making with each of the BI tools. We also plan to involve industry experts to learn from their experience.<\/p>\n<p>A complete list of BI systems and tools to be tested in our experiment is provided below. I want to welcome everyone who is willing to help us in solving this challenge to message me on Telegram  – <a href=\"https:\/\/t.me\/valiotti\">@valiotti<\/a>. I will be glad to hear from you. Although it’s a non-profit project, it’ll be really useful for the open-source community.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/1@2x.jpeg\" width=\"651\" height=\"463.5\" alt=\"\" \/>\n<\/div>\n<p>We plan to cover the following list of tools:<\/p>\n<p><b>Free Open Source:<\/b><\/p>\n<ul>\n<li>Metabase<\/li>\n<li>Redash<\/li>\n<li>Apache Superset<\/li>\n<li>Dash \/ Plotly<\/li>\n<\/ul>\n<p><b>Free Cloud-Based:<\/b><\/p>\n<ul>\n<li>Google Studio<\/li>\n<li>Yandex Datalens<\/li>\n<\/ul>\n<p><b>Paid Cloud-Based:<\/b><\/p>\n<ul>\n<li>Mode<\/li>\n<li>Cluvio<\/li>\n<li>Holistic<\/li>\n<li>Chartio<\/li>\n<li>Periscope<\/li>\n<li>DeltaDNA<\/li>\n<li>Klipfolio<\/li>\n<li>Count.co<\/li>\n<\/ul>\n<p><b>Paid:<\/b><\/p>\n<ul>\n<li>PowerBI<\/li>\n<li>Tableau<\/li>\n<li>Looker<\/li>\n<li>Excel<\/li>\n<li>Alteryx<\/li>\n<li>Qlik Sense<\/li>\n<li>Qlik View<\/li>\n<\/ul>\n<p>The final goal is to evaluate the BI tools against the following criteria:<\/p>\n<ul>\n<li>learning curve of BI tool (1 — too hard to learn, 10 — easy)<\/li>\n<li>tool functionality (1 — very poor functionality, 10 — multifunctional)<\/li>\n<li>ease of use (1 — very inconvenient, 10 — super convenient)<\/li>\n<li>compliance of the result (1 — far from the designed layout, 10 — too close to the designed layout and objective)<\/li>\n<li>visual evaluation (1 — poor appearance, 10 — great visual appearance)<\/li>\n<\/ul>\n<p>An integral weighted score for each tool will be calculated based on the internal estimates.<\/p>\n<p>The results will be posted to our Telegram channel <a href=\"https:\/\/t.me\/leftjoin_en\/\">@leftjoin_en <\/a> and followers will also be able to share their thoughts on the experiment.<br \/>\nBy the end, each tool will be represented as a point in the plane, which will be divided into 4 parts.<\/p>\n<p>This article will be updated with links and ratings as we new posts come out.<\/p>\n",
            "date_published": "2020-10-09T08:57:38+03:00",
            "date_modified": "2020-10-08T10:55:59+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/1@2x.jpeg",
            "_date_published_rfc2822": "Fri, 09 Oct 2020 08:57:38 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "48",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/1@2x.jpeg"
                ]
            }
        },
        {
            "id": "24",
            "url": "https:\/\/en.leftjoin.ru\/all\/analysing-data-on-facebook-ad-campaigns-with-redash\/",
            "title": "Analysing data on Facebook Ad Campaigns with Redash",
            "content_html": "<p>Our previous article was dedicated to collecting data on Facebook ad campaigns. Today we will analyze this data using Redash.  As a first step,  we need to upload our script to AWS cloud and create a server with AIOHTTP before passing the data to Redash. Let’s improve the script a little bit for this task:<\/p>\n<pre class=\"e2-text-code\"><code>from facebook_business.api import FacebookAdsApi\r\nfrom facebook_business.adobjects.adaccount import AdAccount\r\nfrom facebook_business.adobjects.adreportrun import AdReportRun\r\nfrom facebook_business.adobjects.adsinsights import AdsInsights\r\nfrom facebook_business.adobjects.adaccountuser import AdAccountUser as AdUser\r\nfrom facebook_business.exceptions import FacebookRequestError\r\nimport time<\/code><\/pre><p>Redash receives data in JSON format, which we haven’t covered yet. A JSON file is a file that consists of a list of dictionaries. The script will convert it to JSON and pass the data to Redash. We’ll need the variable that stores our access token, app id, app secret and two functions: wait_for_async_job() and get_insights(). The latter function receives account parameters and collects data on ad campaigns. Select the following fields: clicks, impressions, costs and dates.<\/p>\n<p class=\"note\">We need the entire script from our previous article – <a href=\"https:\/\/www.valiotti.com\/leftjoin\/all\/collecting-data-on-facebook-ad-campaigns\/\" class=\"nu\">“<u>Collecting Data on Facebook Ad Campaigns<\/u>”<\/a><\/p>\n<p>The return_json() function will call the get_insights(), which will append data to insights_lists. Since we may have several ad campaigns, our output can be a list of lists with dictionaries instead of just a list of dictionaries. Create a simple lambda expression that will smooth the output and return our insights_lists_flatten. Now, the script returns a list of dictionaries:<\/p>\n<pre class=\"e2-text-code\"><code>def return_json():\r\n   insights_lists = []\r\n   date_preset = 'last_year'\r\n   for elem in my_accounts:\r\n       elem_insights = get_insights(elem, date_preset)\r\n       insights_lists.append(elem_insights)\r\n   flatten = lambda lst: [item for sublist in lst for item in sublist]\r\n   insights_lists_flatten = flatten(insights_lists)\r\n   return insights_lists_flatten<\/code><\/pre><p>We also need  a AIOHTTP server that will return our output as JSON.  Create a new file, import the AIOHTTP library and the get_json() function from the preceding script. Write a simple query handler: the script will receive data from Facebook asynchronously and our asynchronous handler function will sleep until all data is collected and transferred. The function uses json_response to transfer data in json format.<\/p>\n<pre class=\"e2-text-code\"><code>from aiohttp import web\r\nfrom get_json import return_json<\/code><\/pre><pre class=\"e2-text-code\"><code>async def handler(request):\r\n   data = return_json()\r\n   return web.json_response(data)<\/code><\/pre><p>Initialize and run our application.<\/p>\n<pre class=\"e2-text-code\"><code>app = web.Application()\r\napp.add_routes([web.get('\/json', handler)])\r\nweb.run_app(app)<\/code><\/pre><p>Now, go to AWS cloud, create a new folder and upload the two scripts via SFTP connection. Check if the needed port is open, click console — network & security — security groups — default.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/1-1.png\" width=\"1583\" height=\"774\" alt=\"\" \/>\n<\/div>\n<p>Run our file from the server. You can check whether it works by accessing it via server IP address specifying 0880 in the route field.  Connect to Redash using URL and we’ll get the same table returned by our script:<\/p>\n<pre class=\"e2-text-code\"><code>url: server ip<\/code><\/pre><div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/2-1.png\" width=\"881\" height=\"192\" alt=\"\" \/>\n<\/div>\n<p>Having query results, we can write the following query:<\/p>\n<pre class=\"e2-text-code\"><code>select date_start, sum(clicks) as clicks, sum(impressions) as impressions, sum(spend) as spend from query_45\r\ngroup by date_start<\/code><\/pre><p>It returns this table, grouped by the date_start column:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/3-1.png\" width=\"386\" height=\"157\" alt=\"\" \/>\n<\/div>\n<p>We can now plot this data on the chart, let’s see if there is any correlation between ad costs and clicks:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/4-1.png\" width=\"938\" height=\"469\" alt=\"\" \/>\n<\/div>\n<p>Bingo! Next time, we will show you how to get data on ad campaigns from Vkontakte.<\/p>\n",
            "date_published": "2020-05-13T15:25:57+03:00",
            "date_modified": "2020-05-13T15:28:55+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/1-1.png",
            "_date_published_rfc2822": "Wed, 13 May 2020 15:25:57 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "24",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/1-1.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/2-1.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/3-1.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/4-1.png"
                ]
            }
        },
        {
            "id": "22",
            "url": "https:\/\/en.leftjoin.ru\/all\/cohort-analysis-in-redash\/",
            "title": "Cohort analysis in Redash",
            "content_html": "<p>In one of the previous articles we have reviewed <a href=\"all\/retention-rate\/\">building of Retention-report<\/a> and have partially addressed the concept of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cohort_analysis\">cohorts<\/a> therein.<br \/>\nCohort usually implies group of users of a product or a company. Most often, groups are allocated on the basis of time of app installation \/ appearance of a user in a system.<br \/>\nIt turns out, that, using cohort analysis, one can track down how the changes in a product affected the behaviour of users (for example, of old and new users).<\/p>\n<p>Along with that, cohorts can be defined also proceeding from other parameters: geography of a user, traffic source, device platform and other important parameters of your product.<\/p>\n<p>We will figure out, how to compare Retention of users of weekly cohorts in Redash, since Redash has special type of visualization for building such type of report.<br \/>\nFirstly, let’s sort out SQL-query. We still have two tables – <i>user<\/i> (id of a user and time of app installation) and <i>client_session<\/i> – timestamps (<i>created_at<\/i>) of activity of each user (<i>user_id<\/i>). Let’s consider the Retention of the first seven days for last 60 days.<br \/>\nThe query is written in Cloudera Impala, let’s review it.<\/p>\n<p>For starters, let’s build the total size of cohorts:<\/p>\n<pre class=\"e2-text-code\"><code>select trunc(from_unixtime(user.installed_at), &quot;WW&quot;) AS cohort_week, \r\n\tndv(distinct user.id) as cohort_size \/\/counting the number of users in the cohort\r\n\tfrom user \r\n\twhere from_unixtime(user.installed_at) between date_add(now(), -60) and now() \/\/taking registered users for last 60 days\r\ngroup by trunc(from_unixtime(user.installed_at), &quot;WW&quot;)<\/code><\/pre><p>The second part of the query can calculate the quantity of active users for every day during the first thirty days:<\/p>\n<pre class=\"e2-text-code\"><code>select trunc(from_unixtime(user.installed_at), &quot;WW&quot;) AS cohort_week, \r\n        datediff(cast(cs.created_at as timestamp),cast(user.installed_at as timestamp)) as days,\r\n\tndv(distinct user.id) as value  \/\/counting the number of active users for every day\r\n\t\tfrom user \r\n\t\tleft join client_session cs on user.id=cs.user_id\r\nwhere from_unixtime(user.installed_at) between date_add(now(), -60) and now()\r\nand from_unixtime(cs.created_at) &gt;= date_add(now(), -60) \/\/taking sessions for last 60 days\r\nand datediff(cast(cs.created_at as timestamp),cast(user.installed_at as timestamp)) between 0 and 30 \/\/cutting off only the first 30 days of activity\r\ngroup by 1,2<\/code><\/pre><p>Bottom line, all the query entirely:<\/p>\n<pre class=\"e2-text-code\"><code>select size.cohort_week, size.cohort_size, ret.days, ret.value from\r\n(select trunc(from_unixtime(user.installed_at), &quot;WW&quot;) AS cohort_week, \r\n\t\tndv(distinct user.id) as cohort_size \r\n\tfrom user \r\n\twhere from_unixtime(user.installed_at) between date_add(now(), -60) and now()\r\ngroup by trunc(from_unixtime(user.installed_at), &quot;WW&quot;)) size\r\nleft join (select trunc(from_unixtime(user.installed_at), &quot;WW&quot;) AS cohort_week, \r\n        datediff(cast(cs.created_at as timestamp),cast(user.installed_at as timestamp)) as days,\r\n\t\tndv(distinct user.id) as value \r\n\t\tfrom user \r\n\t\tleft join client_session cs on user.id=cs.user_id\r\nwhere from_unixtime(user.installed_at) between date_add(now(), -60) and now()\r\nand from_unixtime(cs.created_at) &gt;= date_add(now(), -60)\r\nand datediff(cast(cs.created_at as timestamp),cast(user.installed_at as timestamp)) between 0 and 30\r\ngroup by 1,2) ret on size.cohort_week=ret.cohort_week<\/code><\/pre><p>Great, now correctly calculated data is available to us.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/cohort-data@2x.png\" width=\"326\" height=\"180\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Data of cohorts in tabular form<\/div>\n<\/div>\n<p>Let’s create new visualization in Redash and indicate the parameters correctly:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/cohort-viz@2x.png\" width=\"589\" height=\"471\" alt=\"\" \/>\n<div class=\"e2-text-caption\">It’s important to indicate the parameters correctly – the columns of the resulting query are compliant therewith.<\/div>\n<\/div>\n<p>Let’s make sure to indicate that we have weekly cohorts:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/cohort-options@2x.png\" width=\"580\" height=\"187\" alt=\"\" \/>\n<\/div>\n<p>Voila, our visualization of cohorts is ready:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/cohort-graph@2x.png\" width=\"807\" height=\"366\" alt=\"\" \/>\n<div class=\"e2-text-caption\">You can add filters and parameters to it and use in a dashboard<\/div>\n<\/div>\n<p>Materials on the topic<\/p>\n<ul>\n<li><a href=\"https:\/\/gopractice.ru\/cohort_analysis\/\">Cohort analysis. Metrics of product vs metrics of growth<\/a><\/li>\n<li><a href=\"https:\/\/medium.com\/analytics-for-humans\/a-beginners-guide-to-cohort-analysis-the-most-actionable-and-underrated-report-on-google-c0797d826bf4\">A beginners guide to cohort analysis<\/a><\/li>\n<\/ul>\n",
            "date_published": "2020-03-03T14:17:54+03:00",
            "date_modified": "2020-05-12T11:19:55+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/cohort-data@2x.png",
            "_date_published_rfc2822": "Tue, 03 Mar 2020 14:17:54 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "22",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/cohort-data@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/cohort-viz@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/cohort-options@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/cohort-graph@2x.png"
                ]
            }
        },
        {
            "id": "16",
            "url": "https:\/\/en.leftjoin.ru\/all\/using-redash-parameters\/",
            "title": "Using parameters in Redash",
            "content_html": "<p>The most convenient and useful thing in Redash is parameters. Parameters can be both in a report and in dashboards.<br \/>\nParameter – is an element of the interface, controlled by a user producing a report.<\/p>\n<p>Parameter in a report can be of the following types:<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"541\" data-ratio=\"1.9049295774648\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/redash-parameter@2x.png\" width=\"541\" height=\"284\" alt=\"\" \/>\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/redash-parameter-v2@2x.png\" width=\"540\" height=\"267\" alt=\"\" \/>\n<\/div>\n<\/div>\n<p>Each type explained separately:<\/p>\n<ul>\n<li><i>Text<\/i> – text input field, can be used in constructions of LIKE type, such parameter <a href=\"https:\/\/redash.io\/help\/user-guide\/querying\/query-parameters#FAQ\">can’t be applied in public dashboards<\/a><\/li>\n<li><i>Number<\/i> – number, entered by a user<\/li>\n<li><i>Dropdown list<\/i> – list of values, from which a user can select just one or several values (not long ago, an option of multi-entry of parameters in a dropdown list appeared)<\/li>\n<li><i>Query dropdown list<\/i> – similarly to the previous one, however the values will be taken from the existing query results<\/li>\n<li><i>Date<\/i> \/ <i>Date and Time<\/i> \/ <i>Date and Time (with seconds)<\/i> – fields of date entry<\/li>\n<li><i>Date Range<\/i> \/ <i>Date and Time Range<\/i> \/ <i>Date and Time Range (with seconds)<\/i> –  fields of date ranges entry.<br \/>\nIt’s convenient to use for the following construction<\/li>\n<\/ul>\n<pre class=\"e2-text-code\"><code>between '{{parameter.start}}' and '{{parameter.end}}'<\/code><\/pre><p>In case of dashboard, a situation might arise, when a parameter is named the same way in several queries, then it will become common for all the dashboard, it’s handy.<\/p>\n<p>One of not obvious, but rather useful solutions: how to make a parameter <b>disabled<\/b>?<br \/>\nLet’s assume, that parameter of “dropdown list” type is named <i>parameter<\/i> and we want to set it for a column <i>geo<\/i> of a table, then the code of the query will look approximately like that:<\/p>\n<pre class=\"e2-text-code\"><code>WHERE\r\n    ('{{parameter}}' = 'Disabled' or geo = '{{parameter}}')<\/code><\/pre><p>At that, surely, ‘Disabled’ should be added to the values of the dropdown list.<\/p>\n",
            "date_published": "2020-01-28T14:22:01+03:00",
            "date_modified": "2020-05-13T14:17:42+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/redash-parameter@2x.png",
            "_date_published_rfc2822": "Tue, 28 Jan 2020 14:22:01 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "16",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/fotorama\/fotorama.css",
                    "system\/library\/fotorama\/fotorama.js",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/redash-parameter@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/redash-parameter-v2@2x.png"
                ]
            }
        },
        {
            "id": "18",
            "url": "https:\/\/en.leftjoin.ru\/all\/redash-alerts\/",
            "title": "Setting up alerts in Redash",
            "content_html": "<p>A very handy function on alert building is implemented in <a href=\"http:\/\/leftjoin.ru\/all\/redash-polnocennaya-on-demand-analitika\/\">Redash<\/a>. Alerts stand for notifications, arising at adjustment of some specific indicator. At that, the degree of change is set manually by a user on his own in the interface. Alerts can be set to a mail or to a channel \/ direct messages Slack.<\/p>\n<p>Let’s recall how to collect the data, using <a href=\"http:\/\/leftjoin.ru\/all\/stroim-funnel-report-v-redash\/\">Google Analytics<\/a>, and set up alerts for this data, applying the internal Redash database (<i>query-results<\/i>). As a foundation for an alert we will focus on the reduction of number of users on the site for the previous day by more than 30%.<\/p>\n<h2>Building a query to Google Analytics<\/h2>\n<pre class=\"e2-text-code\"><code>{\r\n    &quot;ids&quot;: &quot;ga:128886640&quot;,\r\n    &quot;start_date&quot;: &quot;30daysAgo&quot;,\r\n    &quot;end_date&quot;: &quot;yesterday&quot;,\r\n    &quot;metrics&quot;: &quot;ga:users&quot;, \r\n    &quot;dimensions&quot;: &quot;ga:date&quot;\r\n}<\/code><\/pre><p>As a result of performance of this query, we will receive a number of users for the last 30 days.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/ga-query@2x.png\" width=\"175\" height=\"391\" alt=\"\" \/>\n<\/div>\n<h2>Turning on the storage of query results<\/h2>\n<p>One of the main <i>features<\/i> of redash is an opportunity of calling upon the results of query performance, that are stored in the internal DBMS SQLite.<br \/>\nIn order to turn on the storage of results, we need to go to <i>Data Sources<\/i> and turn on <i>query-results (beta)<\/i>.<\/p>\n<p>And now, with a simple command presented below:<\/p>\n<pre class=\"e2-text-code\"><code>select * from query_37<\/code><\/pre><p>we will receive a result, similar to the one of the previous query to GA, however this one has an opportunity of using SQL language for processing of the data set obtained.<\/p>\n<h2>Building a query for evaluation of changes within the number of users<\/h2>\n<p>In order to set up the alert, first of all we need to write a query, that will eventually provide us with a target indicator for check, in our case it is growth or reduction in the number of users on the website.<br \/>\nLets write a query, calling upon the internal DBMS of Redash:<\/p>\n<pre class=\"e2-text-code\"><code>SELECT sum(CASE WHEN date(ga_date)=DATE('now', '-1 day') THEN ga_users ELSE NULL END) AS yesterday,\r\nsum(CASE WHEN date(ga_date)=DATE('now', '-2 day') THEN ga_users ELSE NULL END) AS before_yesterday,\r\n(sum(CASE WHEN date(ga_date)=DATE('now', '-1 day') THEN ga_users ELSE NULL END)*1.0\/\r\nsum(CASE WHEN date(ga_date)=DATE('now', '-2 day') THEN ga_users ELSE NULL END)*1.0-1)*100 AS difference\r\nFROM query_37<\/code><\/pre><p>In the above-shown query we are calculating the number of users for two previous days, and also evaluating the change of number of users in percentage.<br \/>\nIn the current example, we have received the following table of data, that we will use further at the process of alert setting:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/alert-table@2x.png\" width=\"299\" height=\"102\" alt=\"\" \/>\n<\/div>\n<p>Now, in order for us to be able to receive alerts, we need to set query performance by schedule (regular update of results \/ <i>scheduled query<\/i> in redash terminology).<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/refresh-schedule@2x.png\" width=\"351\" height=\"76\" alt=\"\" \/>\n<\/div>\n<p>We set an update for 10 o’clock of every morning:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/refresh-10@2x.png\" width=\"324\" height=\"172\" alt=\"\" \/>\n<\/div>\n<h2>Setting alert<\/h2>\n<p>Going to the menu <i>Create<\/i> – <i>Alert<\/i>. Inserting the name of query, in my case it is “<i>Alert on users<\/i>”.<br \/>\nHereafter, we can change the reflected name of notification or leave the one, proposed by the system.<\/p>\n<p>Choosing a target metric within the example reviewed – <i>difference<\/i>. Below, in the comparison operator (<i>Op<\/i>) selecting <i>less then<\/i> and setting a value of <i>-30<\/i>.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/target-value@2x.png\" width=\"781\" height=\"341\" alt=\"\" \/>\n<\/div>\n<p>In the block on the right you need to select where exactly the alert will be sent. You can read about the setting of alert’s path more thoroughly on the <a href=\"https:\/\/redash.io\/help\/user-guide\/alerts\/creating-new-alert-destination\">official website of Redash<\/a>.<\/p>\n<p>Now, the alert has appeared on the page with the list of alerts and is by default in the status <i>OK<\/i>.<\/p>\n<p>As soon as the indicator exceeds the level that we’ve set, the status will change to <i>TRIGGERED<\/i>, and the alert will be sent to mail \/ to Slack.<\/p>\n<p>More on the topic<\/p>\n<ul>\n<li><a href=\"https:\/\/redash.io\/help\/user-guide\/alerts\/setting-up-an-alert\">Alerts setting up on the page of Redash<\/a><\/li>\n<li><a href=\"https:\/\/redash.io\/help\/user-guide\/alerts\/creating-new-alert-destination#Slack\">Adding Slack as a new destination for alerts<\/a><\/li>\n<\/ul>\n",
            "date_published": "2019-12-03T10:55:11+03:00",
            "date_modified": "2020-05-13T14:19:34+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/ga-query@2x.png",
            "_date_published_rfc2822": "Tue, 03 Dec 2019 10:55:11 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "18",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/ga-query@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/alert-table@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/refresh-schedule@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/refresh-10@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/target-value@2x.png"
                ]
            }
        },
        {
            "id": "17",
            "url": "https:\/\/en.leftjoin.ru\/all\/updates-in-redash-v8\/",
            "title": "Updates in Redash v8",
            "content_html": "<p>Two weeks ago the <a href=\"https:\/\/discuss.redash.io\/t\/final-release-of-redash-v8\/4803\">final release of Redash edition 8<\/a> took place. The complete list of improvements can be found on the <a href=\"https:\/\/discuss.redash.io\/t\/v8-beta-is-here\/4532\">page of beta version of v8 release<\/a>.<\/p>\n<p>In my overview of the novelties, I will focus my attention only on those, that have the most significant impact on user’s experience of Redash utilization, i.e. that are more illustrative for you and me:<\/p>\n<ul>\n<li>Support for multi-select in dropdown (and query dropdown) parameters.<\/li>\n<li>Support for dynamic values in date and date-range parameters.<\/li>\n<li>Search dropdown parameter values.<\/li>\n<li>Pivot Table: support hiding totals.<\/li>\n<li>New Visualization: Details View.<\/li>\n<\/ul>\n<h2>Support for multi-select in dropdown (and query dropdown) parameters.<\/h2>\n<p>In the 8th version of Redash we finally receive the long-awaited support of selection of several values in a parameter such as “dropdown list” or “dropdown list on the basis of the query”:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/dropdown-multiple@2x.png\" width=\"497\" height=\"306\" alt=\"\" \/>\n<\/div>\n<p>When we select several different clues, the above-mentioned values transform into a list, divided by a comma. At that, there is an opportunity to wrap the values of such a list into single quotes or double quotes.<\/p>\n<div class=\"e2-text-picture\">\n<div class=\"fotorama\" data-width=\"434\" data-ratio=\"3.8407079646018\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/multiple-quotation@2x.png\" width=\"434\" height=\"113\" alt=\"\" \/>\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/single-double-quotation@2x.png\" width=\"476\" height=\"143\" alt=\"\" \/>\n<\/div>\n<\/div>\n<p>For us it means an opportunity to use requirements of IN type with a parameter in the queries:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/select-in@2x.png\" width=\"573\" height=\"215\" alt=\"\" \/>\n<\/div>\n<p>At application of such parameter values, we will receive the following URL in the line of the browser:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/url-parameter@2x.png\" width=\"383\" height=\"33\" alt=\"\" \/>\n<\/div>\n<h2>Support for dynamic values in date and date-range parameters.<\/h2>\n<p>Extremely handy and useful feature for selection of dates, that is often used in Tableau, however hadn’t been implemented into Redash until recently: utilization of dynamic values for dates:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/dynamic-dates@2x.png\" width=\"785\" height=\"414\" alt=\"\" \/>\n<\/div>\n<p>Pressing the zipper button, you can select a random period, and Redash will insert the required values into the query on its own. Thus, for instance, you can quickly look through the statistics for last week or last month.<\/p>\n<h2>Search dropdown parameter values.<\/h2>\n<p>Let’s assume that we are using a parameter of a type “dropdown list on the basis of the query”, and in the query selected there are more than 300 resulting lines, based on which we need to find a value of our interest. In the 8th version this problem is solved by auto-complete and search by parameter values. In the example below I am inserting a line “<i>Orga<\/i>” and obtain all the values, in which this line is met, very convenient.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/search-autocomplete-v8@2x.png\" width=\"450\" height=\"270\" alt=\"\" \/>\n<\/div>\n<h2>Pivot Table: support hiding totals.<\/h2>\n<p>Quite long-awaited feature, that allows to aggregate outcomes by rows \/ columns.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/totals@2x.png\" width=\"260\" height=\"286\" alt=\"\" \/>\n<\/div>\n<h2>New Visualization: Details View<\/h2>\n<p>New presentation of data results: view of details by each line. I assume, it can be convenient at use in a dashboard, when you apply filtration by a specific user \/ partner.<br \/>\nIt visualizes the names of columns and results of a specific line in a table form.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/details-view@2x.png\" width=\"490\" height=\"251\" alt=\"\" \/>\n<\/div>\n",
            "date_published": "2019-11-25T16:03:18+03:00",
            "date_modified": "2020-05-13T14:20:32+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/dropdown-multiple@2x.png",
            "_date_published_rfc2822": "Mon, 25 Nov 2019 16:03:18 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "17",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/fotorama\/fotorama.css",
                    "system\/library\/fotorama\/fotorama.js"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/dropdown-multiple@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/multiple-quotation@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/single-double-quotation@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/select-in@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/url-parameter@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/dynamic-dates@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/search-autocomplete-v8@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/totals@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/details-view@2x.png"
                ]
            }
        },
        {
            "id": "12",
            "url": "https:\/\/en.leftjoin.ru\/all\/retention-rate\/",
            "title": "How to calculate Retention?",
            "content_html": "<p>In this post we will discover, how to properly construct a report on Retention with application of <a href=\"all\/redash-full-fledged-on-demand-analytics\/\">Redash<\/a> and SQL language.<br \/>\nFor starters, let’s explain in a nutshell what the metric <b>Retention rate<\/b> is, why it is important,<\/p>\n<h2>Retention rate<\/h2>\n<p><b>Retention rate<\/b> metric is widespread and is particularly popular within the mobile industry, since it allows to understand how well a product engages the users into daily use. Let’s recall (or discover), how <b>Retention<\/b> is calculated:<\/p>\n<p>Retention of day <i>X<\/i> – is <i>N%<\/i> of users that will return to the product on day <i>X<\/i>. In other words, if on some specific day (day 0) 100 new users came, and 15 returned on the first day, then Retention of the 1st day will be equal to 15\/100=15%.<br \/>\nMost commonly, Retention of days 1, 3, 7 and 30 are singled out as the most descriptive metrics of a product, however it’s useful to address Retention curve as a whole and make conclusions, proceeding from it.<\/p>\n<h2>Retention curve<\/h2>\n<p>In the end, we are interested in construction of such curve, that shows the retention of users from day 0 to day 30.<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/Retention@2x.png\" width=\"585\" height=\"200\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Retention rate curve from day 0 do day 30<\/div>\n<\/div>\n<h2>Rolling Retention (RR)<\/h2>\n<p>Besides classic Retention rate, Rolling Retention (hereinafter, RR) is allocated. At calculation of RR, apart from day X, all the subsequent days are also considered. Thus, RR of the 1st day – the amount of users who returned on the 1st and subsequent days.<\/p>\n<p>Let’s compare Retention and Rolling Retention of the 10th day:<br \/>\n<b>Retention<sub>10<\/sub><\/b> — the amount of users, who returned on the 10th day \/ the amount of users, who installed the app 10 days ago * 100%.<br \/>\n<b>Rolling Retention<sub>10<\/sub><\/b> — the amount of users, who returned on the 10th day <i>or later<\/i> \/ the amount of users, who installed the app 10 days ago * 100%.<\/p>\n<h2>Granularity (retention of time periods)<\/h2>\n<p>In some industries and respective tasks, it is useful to understand the Retention of a specific day (most often, in the mobile industry), in other cases it is useful to understand the retention of users on various time intervals: for example, weekly or monthly periods (oftentimes, it’s handy in e-commerce, retail).<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/Monthly-Retention@2x.png\" width=\"669\" height=\"527\" alt=\"\" \/>\n<div class=\"e2-text-caption\">An example of cohorts by months and monthly Retention respective thereto<\/div>\n<\/div>\n<h2>How to build a Retention report on SQL language?<\/h2>\n<p>We have sorted out above how to calculate Retention in formulas. Now let’s apply it with SQL language.<br \/>\nLet’s assume, that we have two tables: <i>user<\/i> — storing data about users’ identifiers and meta-information, <i>client_session<\/i> — information on visits of the mobile app by users.<br \/>\nOnly these two tables will be present in the query, so you can easily adapt the query to yourself.<br \/>\n<i>note<\/i>: within this code, I am using Impala as DBMS.<\/p>\n<h3>Collecting the size of cohorts<\/h3>\n<pre class=\"e2-text-code\"><code>SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          ndv(user.id) AS users\r\n   FROM USER\r\n   WHERE from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1<\/code><\/pre><p>Let’s sort out this pretty simple query: for every day we calculate the number of unique users for the period [60 days ago; 31 days ago].<br \/>\nIn order not to mess with documentation: command <i>ndv()<\/i> in Impala is analogue of a command <i>count(distinct)<\/i>.<\/p>\n<h3>Calculating the number of returned users on each cohort<\/h3>\n<pre class=\"e2-text-code\"><code>SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) AS date_diff,\r\n          ndv(user.id) AS ret_base\r\n   FROM USER\r\n   LEFT JOIN client_session cs ON cs.user_id=user.id\r\n   WHERE 1=1\r\n     AND datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) between 0 and 30\r\n     AND from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1, 2<\/code><\/pre><p>In this query, the key part is contained in the command <i>datediff<\/i>: now we are calculating for each cohort and for each <i>datediff<\/i> the number of unique users with the very same command <i>ndv()<\/i> (practically, the number of users, who returned within the days from 0 to 30).<\/p>\n<p>Great, now we have the size of cohorts and the number of returned users.<\/p>\n<h3>Combining all together<\/h3>\n<pre class=\"e2-text-code\"><code>SELECT reg.reg_date AS date_registration,\r\n       reg.users AS cohort_size,\r\n       cohort.date_diff AS day_difference,\r\n       cohort.ret_base AS retention_base,\r\n       cohort.ret_base\/reg.users AS retention_rate\r\nFROM\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          ndv(user.id) AS users\r\n   FROM USER\r\n   WHERE from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1) reg\r\nLEFT JOIN\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) AS date_diff,\r\n          ndv(user.id) AS ret_base\r\n   FROM USER\r\n   LEFT JOIN client_session cs ON cs.user_id=user.id\r\n   WHERE 1=1\r\n     AND datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) between 0 and 30\r\n     AND from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1, 2) cohort ON reg.reg_date=cohort.reg_date\r\n    ORDER BY 1,3<\/code><\/pre><p>We have received the query, that calculates <b>Retention<\/b> for each cohort, and, eventually, the result can be displayed as follows:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/Cohort-retention@2x.png\" width=\"585\" height=\"200\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Retention rate, calculated for each cohort of users<\/div>\n<\/div>\n<h3>Construction of the sole Retention curve<\/h3>\n<p>Let’s modify our query a bit and obtain the data for construction of one Retention curve:<\/p>\n<pre class=\"e2-text-code\"><code>SELECT \r\n       cohort.date_diff AS day_difference,\r\n       avg(reg.users) AS cohort_size,\r\n       avg(cohort.ret_base) AS retention_base,\r\n       avg(cohort.ret_base)\/avg(reg.users)*100 AS retention_rate\r\nFROM\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          ndv(user.id) AS users\r\n   FROM USER\r\n   WHERE from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1) reg\r\nLEFT JOIN\r\n  (SELECT from_unixtime(user.installed_at, &quot;yyyy-MM-dd&quot;) AS reg_date,\r\n          datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) AS date_diff,\r\n          ndv(user.id) AS ret_base\r\n   FROM USER\r\n   LEFT JOIN client_session cs ON cs.user_id=user.id\r\n   WHERE 1=1\r\n     AND datediff(cast(cs.created_at AS TIMESTAMP), cast(installed_at AS TIMESTAMP)) between 0 and 30\r\n     AND from_unixtime(user.installed_at)&gt;=date_add(now(), -60)\r\n     AND from_unixtime(user.installed_at)&lt;=date_add(now(), -31)\r\n   GROUP BY 1,2) cohort ON reg.reg_date=cohort.reg_date\r\n    GROUP BY 1        \r\n    ORDER BY 1<\/code><\/pre><p>Now, we have average by all the cohorts <b>Retention rate<\/b>, calculated for each day.<\/p>\n<h2>More on the subject<\/h2>\n<ul>\n<li><a href=\"https:\/\/gopractice.ru\/retention\/\">How to create products, forming habits?<\/a><\/li>\n<li><a href=\"https:\/\/www.braze.com\/blog\/calculate-retention-rate\/\">Top 3 Ways To Calculate User Retention Rate With Formulas<\/a><\/li>\n<\/ul>\n",
            "date_published": "2019-11-03T16:27:55+03:00",
            "date_modified": "2020-05-13T14:20:47+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/Retention@2x.png",
            "_date_published_rfc2822": "Sun, 03 Nov 2019 16:27:55 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "12",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/Retention@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/Monthly-Retention@2x.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/Cohort-retention@2x.png"
                ]
            }
        },
        {
            "id": "7",
            "url": "https:\/\/en.leftjoin.ru\/all\/stroim-funnel-report-v-redash\/",
            "title": "Building a funnel-report in redash",
            "content_html": "<p>So, we’ve been planning to review Funnel-visualization of a report in Redash.<br \/>\nFirst and foremost, let’s build a request <a href=\"https:\/\/www.valiotti.com\/leftjoin\/all\/how-to-connect-google-analytics-to-redash\/\">to the data source that we’ve created<\/a> – Google Analytics.<\/p>\n<p>The following text needs to be placed in the request console:<\/p>\n<pre class=\"e2-text-code\"><code>{\r\n    &quot;ids&quot;: &quot;ga:128886640&quot;,\r\n    &quot;start_date&quot;: &quot;30daysAgo&quot;,\r\n    &quot;end_date&quot;: &quot;yesterday&quot;,\r\n    &quot;metrics&quot;: &quot;ga:users,ga:goal1Completions,ga:goal2Completions,ga:goal3Completions&quot;\r\n}<\/code><\/pre><p>In this request we are asking API Google Analytics to provide data for the last 30 days on the account GA: 128886640. We want to see the number of users and the number of completion of goals 1, 2 and 3.<\/p>\n<p>As a result, our table will look as follows:<\/p>\n<div class=\"e2-text-table\">\n<table cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n<tr>\n<td><b>ga:users<\/b><\/td>\n<td><b>ga:goal1Completions<\/b><\/td>\n<td><b>ga:goal2Completions<\/b><\/td>\n<td><b>ga:goal3Completions<\/b><\/td>\n<\/tr>\n<tr>\n<td>3,926<\/td>\n<td>105<\/td>\n<td>41<\/td>\n<td>32<\/td>\n<\/tr>\n<\/table>\n<\/div>\n<p>Great, that’s right what we need in order to build a funnel.<br \/>\nNow I will tell you about one very useful Redash feature: <i>query-results<\/i>. In order to connect tables with results of queries’ execution, we go to <i>Data Sources<\/i> and search for <i>query-results (beta)<\/i>. Connecting new data source.<br \/>\nNow we have an opportunity to refer to results of Redash queries. Thus, for instance, we can use the results of a requests to Google Analytics API.<\/p>\n<p><b>How to do it?<\/b><br \/>\nWe need to choose a data source query-results on the left:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/query-results.png\" width=\"350\" height=\"78\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Drop down menu with selection of data sources (in the console – on the left)<\/div>\n<\/div>\n<p>Now we’ll learn to make funnel-visualization. For this purpose, we write the following SQL-query:<\/p>\n<pre class=\"e2-text-code\"><code>select 'Add a good to the shopping cart' as step_name, ga_goal1Completions as goalCompletion from query_8\r\nunion all\r\nselect 'View the shopping cart' as step_name, ga_goal2Completions from query_8\r\nunion all\r\nselect 'Order processing' as step_name, ga_goal3Completions from query_8<\/code><\/pre><p>In this case <i>query_8<\/i> – is the very table with results of request to the data source Google Analytics.<\/p>\n<p>Let’s set visualization:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/visualisation.png\" width=\"600\" height=\"513\" alt=\"\" \/>\n<div class=\"e2-text-caption\">Carefully selecting parameters, in order to achieve the desired result<\/div>\n<\/div>\n<p>As a result, we receive the funnel of conversions from one goal to another:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/en.leftjoin.ru\/pictures\/funnel.png\" width=\"600\" height=\"152\" alt=\"\" \/>\n<div class=\"e2-text-caption\">You can display this funnel in the dashboard and add filters \/ parameters thereto.<\/div>\n<\/div>\n",
            "date_published": "2018-12-04T14:36:00+03:00",
            "date_modified": "2020-05-13T14:23:11+03:00",
            "image": "https:\/\/en.leftjoin.ru\/pictures\/query-results.png",
            "_date_published_rfc2822": "Tue, 04 Dec 2018 14:36:00 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "7",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css",
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/en.leftjoin.ru\/pictures\/query-results.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/visualisation.png",
                    "https:\/\/en.leftjoin.ru\/pictures\/funnel.png"
                ]
            }
        }
    ],
    "_e2_version": 3386,
    "_e2_ua_string": "E2 (v3386; Aegea)"
}