{"id":46627,"date":"2021-01-06T00:00:00","date_gmt":"2021-01-06T08:00:00","guid":{"rendered":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/"},"modified":"2025-11-13T12:55:08","modified_gmt":"2025-11-13T20:55:08","slug":"advanced-sql-queries-for-anomaly-detection-and-business-reports","status":"publish","type":"post","link":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/","title":{"rendered":"Advanced SQL Queries for Anomaly Detection and Business Reports"},"content":{"rendered":"<h1>Introduction and Purpose<\/h1>\n<h3>The Use Case<\/h3>\n<p>Although we often think of the <strong>Internet of Things<\/strong> as something that coordinates moving entities. In fact, many companies in the industry deal with stationary devices. One example is a smart metering system that measures power consumption in a building facility and delivers time series data in the granularity that allows developing power-saving strategies.<\/p>\n<h3>Objectives<\/h3>\n<p>We will create a business report that compares power consumption in the last seven days split per day of the week against the average consumption per day of the week in the whole previous period of time.<\/p>\n<p>This approach aims to detect anomalies, unveil power consumption patterns, and routinely monitor increases and decreases in power consumption that may result in an unintended high cost.<\/p>\n<h3>Methods<\/h3>\n<p>The article will explain how to build an advanced SQL query that transforms time series data from the <strong>GridDB<\/strong> database into an aggregation.<\/p>\n<p>The query will use a few essential SQL time functions. A detailed commentary on their utilization will be provided.<\/p>\n<p>The tutorial will walk you through the process of creating a query with multiple nested subqueries and explain how to combine them without losing an overview of the whole structure.<\/p>\n<h3>Prerequisites<\/h3>\n<p>To use the materials from this article, you need to install an SQL client, for instance, SQLWorkbench\/J as described in one of the previous GridDB blog posts <a href=\"https:\/\/griddb.net\/en\/blog\/connecting-to-griddb-via-jdbc-with-sqlworkbench-j\/\">here<\/a>.<\/p>\n<h1>Tutorial<\/h1>\n<h2>Raw Data<\/h2>\n<p>The smart meters produce a timestamp twice in a minute. The database has only two columns: datetime in the timestamp format and power in a float format.<\/p>\n<p>Many single entries in the database have very small values in the power column, and there are 2,880 entries being produced each day. It is quite challenging to make any meaningful conclusions without an aggregation.<\/p>\n<p>On the other side, it seems quite intuitive that power consumption varies depending on the day of the week: we do not need much power during the week at our homes, but on the weekend, we use a lot of it. On the contrary, the office building would demonstrate high consumption on the weekdays and low consumption on Saturday and Sunday. That&#8217;s why we stick to the day of the week as an important dimension in our report.<\/p>\n<p>Let us first check the raw data, though.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT \n    datetime, \n    power \nFROM \n  power2 \nLIMIT 10\n<\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          datetime\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          2020-12-01 04:00:23\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          2020-12-01 04:00:53\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2020-12-01 04:01:23\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          2020-12-01 04:01:53\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          2020-12-01 04:02:23\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          2020-12-01 04:02:53\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          2020-12-01 04:03:23\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          7\n        <\/th>\n<td>\n          2020-12-01 04:03:53\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          8\n        <\/th>\n<td>\n          2020-12-01 04:04:23\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          9\n        <\/th>\n<td>\n          2020-12-01 04:04:53\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Extracting day of the week<\/h2>\n<p>GridDB supports the native SQL <strong>EXTRACT()<\/strong> function that helps to separate components of the date, including year, month, day, day of week, etc.<\/p>\n<p>EXTRACT() returns a value in the numeric format. Since we will be using day of week (further referred to as DOW) for aggregating the data, we directly convert it into the string format. An aggregation dimension is not allowed in any format that can be aggregated itself.<\/p>\n<p>We simply wrap one function into the other in the query to get the necessary result.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT \n     CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW,\n     power\nFROM \n  power2\nLIMIT 10\n<\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          7\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          8\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          9\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.0000000000000000120000043\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>It&#8217;s time for the first subquery: SQL won&#8217;t let us group by DOW right here after we&#8217;ve just created this new column. We &#8220;nest&#8221; the first query into the new one that we further use for aggregation.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT\n    DOW,\n    SUM(power) as power\nFROM \n    (SELECT \n        power, \n        CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n    FROM power2\n    ) AS TEST \nGROUP BY DOW\n<\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          0\n        <\/td>\n<td>\n          14781000.21\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          1\n        <\/td>\n<td>\n          10222437.23\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          6996719.71\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          3\n        <\/td>\n<td>\n          17502268.22\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          4\n        <\/td>\n<td>\n          15799145.37\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          5\n        <\/td>\n<td>\n          15348122.85\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          6\n        <\/td>\n<td>\n          14864972.17\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Average Consumption per Each Day of Week<\/h2>\n<p>We need to keep in mind that we have summed up power consumption for the whole period of time available in the database. We cannot really compare it against only one-week consumption. Nor can we just calculate an average instead of the sum, since this would produce a mean value for the single entries in the table but not an average per day of week.<\/p>\n<p>To solve this problem, we need to count how many times each day of week appears in the data to use it as a divider. We count the number of rows with the SQL native <strong>COUNT()<\/strong> function. By doing so, we get the number of timestamps produced on a day, and then we divide it by 2 * 60 * 24 to get the number of days.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT\n    DOW,\n    COUNT(power) \/ (2 * 60 * 24) AS count_days,\n    SUM(power) as power\nFROM \n    (SELECT \n        power, \n        CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n    FROM power2\n    ) AS TEST \nGROUP BY DOW\n<\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW\n        <\/th>\n<th>\n          count_days\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          0\n        <\/td>\n<td>\n          3\n        <\/td>\n<td>\n          14781000.21\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          1\n        <\/td>\n<td>\n          3\n        <\/td>\n<td>\n          10222437.23\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          4\n        <\/td>\n<td>\n          6996719.71\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          3\n        <\/td>\n<td>\n          4\n        <\/td>\n<td>\n          17502268.22\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          4\n        <\/td>\n<td>\n          3\n        <\/td>\n<td>\n          15799145.37\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          5\n        <\/td>\n<td>\n          4\n        <\/td>\n<td>\n          15348122.85\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          6\n        <\/td>\n<td>\n          3\n        <\/td>\n<td>\n          14864972.17\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>We do not need one more output column in the result, so we move the expression counting the unique DOWs and calculate the real average power consumption per day of week straightforwardly in the main query.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">\nSELECT\n    DOW,\n    SUM(power) \/ (COUNT(power) \/ (2 * 60 * 24)) as power\nFROM \n    (SELECT \n        power, \n        CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n    FROM power2\n    ) AS TEST \nGROUP BY DOW\n<\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          0\n        <\/td>\n<td>\n          4927000.07\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          1\n        <\/td>\n<td>\n          3407479.08\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          1749179.93\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          3\n        <\/td>\n<td>\n          4375567.06\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          4\n        <\/td>\n<td>\n          5266381.79\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          5\n        <\/td>\n<td>\n          3837030.71\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          6\n        <\/td>\n<td>\n          4954990.72\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<h2>Filter the Last Seven Days<\/h2>\n<p>Now, when we are set with the first part of our comparison, let&#8217;s move to finding out power consumption per day of week for the last seven days. We can use the previous query but we do not need to calculate the number of days: Each DOW appears only once.<\/p>\n<p>Instead, we have to limit the data to the last seven days. How to look back into the past?<\/p>\n<p>We use <strong>NOW()<\/strong> as our starting point. NOW() produces the timestamp with the date and time of the moment when the query is performed.<\/p>\n<p>We further utilize the <strong>TIMESTAMP_ADD()<\/strong> function that is supported by GridDB. This one transforms a timestamp value. TIMESTAMP_ADD() can change different parts of it: year, month, day, hour, second, and millisecond. Although it looks like it can only add something, it can also do the reverse thing. For this purpose, we specify the argument as a negative number.<\/p>\n<p>Simple magic!<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">\nSELECT\n    DOW,\n    SUM(power) as power\nFROM \n    (SELECT \n        power, \n        CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n    FROM power2\n    WHERE datetime > TIMESTAMP_ADD(DAY, NOW(), -7)\n    AND datetime &lt; = NOW()\n    ) AS TEST \nGROUP BY DOW\n<\/code>&lt;\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW\n        <\/th>\n<th>\n          power\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          0\n        <\/td>\n<td>\n          3332113.50\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          1\n        <\/td>\n<td>\n          3164761.58\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          0.00\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          3\n        <\/td>\n<td>\n          1413780.69\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          4\n        <\/td>\n<td>\n          3025183.71\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          5\n        <\/td>\n<td>\n          3062583.10\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          6\n        <\/td>\n<td>\n          3252764.84\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>We have added a double <strong>WHERE<\/strong> clause to filter the data. Just in case the data have some strange values with the timestamps lying in the future, we sort them out by specifying the upper limit as NOW().<\/p>\n<h2>Match the Results by Using the SQL Join<\/h2>\n<p>We will use the SQL <strong>JOIN<\/strong> command to glue two queries together and match power consumption for both time periods. To differentiate between the origins of the columns in our output result, we will do some renaming. Each column in the first query will get <em>_alltime<\/em> at the end of it and the columns in the second query will receive <em>_lastweek<\/em> as a label.<\/p>\n<p>SQL JOIN requires us to give aliases to the subqueries, too, to be able to specify the key: A column that will be used to match values from both subqueries.<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT * FROM\n\n    (SELECT\n        DOW as DOW_alltime,\n        SUM(power) \/ (COUNT(power) \/ (2 * 60 * 24)) as power_alltime\n    FROM \n        (SELECT \n            power, \n            CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n        FROM power2\n        ) AS TEST_alltime \n    GROUP BY DOW_alltime) as ALLTIME\n\nJOIN\n\n    (SELECT\n        DOW as DOW_lastweek,\n        SUM(power) as power_lastweek\n    FROM \n        (SELECT \n            power, \n            CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n        FROM power2\n        WHERE datetime > TIMESTAMP_ADD(DAY, NOW(), -7)\n        AND datetime &lt; = NOW()\n        ) AS TEST_lastweek \n    GROUP BY DOW_lastweek) as LASTWEEK\n\nON \n\nALLTIME.DOW_alltime = LASTWEEK.DOW_lastweek\n<\/code>&lt;\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          DOW_alltime\n        <\/th>\n<th>\n          power_alltime\n        <\/th>\n<th>\n          DOW_lastweek\n        <\/th>\n<th>\n          power_lastweek\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          0\n        <\/td>\n<td>\n          4927000.07\n        <\/td>\n<td>\n          0\n        <\/td>\n<td>\n          3332113.50\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          1\n        <\/td>\n<td>\n          3407479.08\n        <\/td>\n<td>\n          1\n        <\/td>\n<td>\n          3164761.58\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          2\n        <\/td>\n<td>\n          1749179.93\n        <\/td>\n<td>\n          2\n        <\/td>\n<td>\n          0.00\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          3\n        <\/td>\n<td>\n          4375567.06\n        <\/td>\n<td>\n          3\n        <\/td>\n<td>\n          1413780.69\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          4\n        <\/td>\n<td>\n          5266381.79\n        <\/td>\n<td>\n          4\n        <\/td>\n<td>\n          3025183.71\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          5\n        <\/td>\n<td>\n          3837030.71\n        <\/td>\n<td>\n          5\n        <\/td>\n<td>\n          3062583.10\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          6\n        <\/td>\n<td>\n          4954990.72\n        <\/td>\n<td>\n          6\n        <\/td>\n<td>\n          3252764.84\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>We are set to proceed to the final report!<\/p>\n<h2>The Final Report<\/h2>\n<p>We will do some prettifying to make the final table more readable and possible anomalies more eye-catching:<\/p>\n<ul>\n<li>get rid of one of the DOW-columns since they are otherwise identical<\/li>\n<li>rename DOW values to make them look human<\/li>\n<li>calculate a delta consumption as the difference between the last-week consumption and the overall average consumption. <\/li>\n<li>add a column with only two values &#8211; either &#8220;increased&#8221; or &#8220;decreased&#8221; &#8211; to make the differences stand out and easy to classify<\/li>\n<li>last but not least, change the order of the columns, starting with the DOW on the very left, followed by the new semi-grouping column, and then by all numeric columns<\/li>\n<\/ul>\n<p>Just look at the monster query we&#8217;ve got in the end!<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"lang-sql\">SELECT \n\n    CASE DOW_alltime\n        WHEN '1' THEN 'Monday'\n        WHEN '2' THEN 'Tuesday'\n        WHEN '3' THEN 'Wednesday'\n        WHEN '4' THEN 'Thursday'\n        WHEN '5' THEN 'Friday'\n        WHEN '6' THEN 'Saturday'\n        WHEN '0' THEN 'Sunday'\n    end\n    as day_of_week,\n    case \n        when (power_alltime - power_lastweek) > 0 then 'descreased'\n        when (power_alltime - power_lastweek) &lt; 0 then 'increased'\n        else 'the same'\n    end as status,\n    power_alltime,\n    power_lastweek,\n    power_alltime - power_lastweek as power_usage_delta\n\nFROM\n\n    (SELECT\n        SUM(power) \/ (COUNT(power) \/ (2 * 60 * 24)) as power_alltime,\n        DOW as DOW_alltime\n    FROM \n        (SELECT \n            power, \n            CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n        FROM power2\n        ) AS TEST_alltime \n    GROUP BY DOW_alltime) as ALLTIME\n\nJOIN\n\n    (SELECT\n        SUM(power) as power_lastweek,\n        DOW as DOW_lastweek\n    FROM \n        (SELECT \n            power, \n            CAST(EXTRACT(DAY_OF_WEEK, datetime) as STRING) AS DOW \n        FROM power2\n        WHERE datetime > TIMESTAMP_ADD(DAY, NOW(), -7)\n        AND datetime &lt; = NOW()\n        ) AS TEST_lastweek \n    GROUP BY DOW_lastweek) as LASTWEEK\n\nON \n\nALLTIME.DOW_alltime = LASTWEEK.DOW_lastweek\n<\/code>&lt;\/code><\/pre>\n<\/div>\n<div>\n<style scoped>\n    .dataframe tbody tr th:only-of-type {\n        vertical-align: middle;\n    }<\/p>\n<p>    .dataframe tbody tr th {\n        vertical-align: top;\n    }<\/p>\n<p>    .dataframe thead th {\n        text-align: right;\n    }\n  <\/style>\n<table border=\"1\" class=\"dataframe\">\n<thead>\n<tr style=\"text-align: right;\">\n<th>\n        <\/th>\n<th>\n          day_of_week\n        <\/th>\n<th>\n          status\n        <\/th>\n<th>\n          power_alltime\n        <\/th>\n<th>\n          power_lastweek\n        <\/th>\n<th>\n          power_usage_delta\n        <\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<th>\n          0\n        <\/th>\n<td>\n          Sunday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          4927000.07\n        <\/td>\n<td>\n          3332113.50\n        <\/td>\n<td>\n          1594886.57\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          1\n        <\/th>\n<td>\n          Monday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          3407479.08\n        <\/td>\n<td>\n          3164761.58\n        <\/td>\n<td>\n          242717.50\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          2\n        <\/th>\n<td>\n          Tuesday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          1749179.93\n        <\/td>\n<td>\n          0.00\n        <\/td>\n<td>\n          1749179.93\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          3\n        <\/th>\n<td>\n          Wednesday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          4375567.06\n        <\/td>\n<td>\n          1413780.69\n        <\/td>\n<td>\n          2961786.36\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          4\n        <\/th>\n<td>\n          Thursday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          5266381.79\n        <\/td>\n<td>\n          3025183.71\n        <\/td>\n<td>\n          2241198.08\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          5\n        <\/th>\n<td>\n          Friday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          3837030.71\n        <\/td>\n<td>\n          3062583.10\n        <\/td>\n<td>\n          774447.61\n        <\/td>\n<\/tr>\n<tr>\n<th>\n          6\n        <\/th>\n<td>\n          Saturday\n        <\/td>\n<td>\n          descreased\n        <\/td>\n<td>\n          4954990.72\n        <\/td>\n<td>\n          3252764.84\n        <\/td>\n<td>\n          1702225.88\n        <\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>This kind of report helps to keep an eye on any undesirable changes in the power consumption patterns.<\/p>\n<p>It allows to pick up anomalies, such as unexpectedly high power consumption on a particular day of week, quickly. The report can be exported and sent to any interested persons to help them recognize the need for action and facilitate decision-making.<\/p>\n<h1>Advantages of Using Open-Source Tools for Building Business Reports<\/h1>\n<p>Despite that the numerous paid business insights tools are available nowadays, old (like SQL) and new (like GridDB) open-source ones can provide the same quality and even more flexibility for building sophisticated reports.<\/p>\n<p>GridDB supports <a href=\"https:\/\/docs.griddb.net\/sqlreference\/sql-commands-supported\/\">a wide range of SQL commands<\/a> with the focus on time functions. GridDB can host vast amounts of data without query performance suffering a millisecond of a delay.<\/p>\n<h1>A Short Afterward<\/h1>\n<p>We hope that this tutorial also helped you to catch the logic of writing advanced SQL queries and may encourage you to use them on a routine basis.<\/p>\n<p>Happy querying!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many companies in the industry deal with stationary devices. One example is a smart metering system that measures power consumption in a building facility and delivers time series data in the granularity [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":27179,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-46627","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many\" \/>\n<meta property=\"og:url\" content=\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-06T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-13T20:55:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2400\" \/>\n\t<meta property=\"og:image:height\" content=\"1600\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"griddb-admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"griddb-admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\"},\"author\":{\"name\":\"griddb-admin\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\"},\"headline\":\"Advanced SQL Queries for Anomaly Detection and Business Reports\",\"datePublished\":\"2021-01-06T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:55:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\"},\"wordCount\":1351,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\",\"url\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\",\"name\":\"Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\/\/griddb.net\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage\"},\"thumbnailUrl\":\"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg\",\"datePublished\":\"2021-01-06T08:00:00+00:00\",\"dateModified\":\"2025-11-13T20:55:08+00:00\",\"description\":\"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage\",\"url\":\"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg\",\"contentUrl\":\"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg\",\"width\":2400,\"height\":1600},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/griddb.net\/en\/#website\",\"url\":\"https:\/\/griddb.net\/en\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL\",\"publisher\":{\"@id\":\"https:\/\/griddb.net\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/griddb.net\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/griddb.net\/en\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\/\/griddb.net\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/griddbcommunity\/\",\"https:\/\/x.com\/GridDBCommunity\",\"https:\/\/www.linkedin.com\/company\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233\",\"name\":\"griddb-admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g\",\"caption\":\"griddb-admin\"},\"url\":\"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT","description":"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/","og_locale":"en_US","og_type":"article","og_title":"Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT","og_description":"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many","og_url":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2021-01-06T08:00:00+00:00","article_modified_time":"2025-11-13T20:55:08+00:00","og_image":[{"width":2400,"height":1600,"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg","type":"image\/jpeg"}],"author":"griddb-admin","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"griddb-admin","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#article","isPartOf":{"@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/"},"author":{"name":"griddb-admin","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233"},"headline":"Advanced SQL Queries for Anomaly Detection and Business Reports","datePublished":"2021-01-06T08:00:00+00:00","dateModified":"2025-11-13T20:55:08+00:00","mainEntityOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/"},"wordCount":1351,"commentCount":0,"publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/","url":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/","name":"Advanced SQL Queries for Anomaly Detection and Business Reports | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/griddb.net\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage"},"image":{"@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg","datePublished":"2021-01-06T08:00:00+00:00","dateModified":"2025-11-13T20:55:08+00:00","description":"Introduction and Purpose The Use Case Although we often think of the Internet of Things as something that coordinates moving entities. In fact, many","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/blog\/advanced-sql-queries-for-anomaly-detection-and-business-reports\/#primaryimage","url":"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg","contentUrl":"\/wp-content\/uploads\/2020\/12\/caspar-camille-rubin-fPkvU7RDmCo-unsplash.jpg","width":2400,"height":1600},{"@type":"WebSite","@id":"https:\/\/griddb.net\/en\/#website","url":"https:\/\/griddb.net\/en\/","name":"GridDB: Open Source Time Series Database for IoT","description":"GridDB is an open source time-series database with the performance of NoSQL and convenience of SQL","publisher":{"@id":"https:\/\/griddb.net\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/griddb.net\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/griddb.net\/en\/#organization","name":"Fixstars","url":"https:\/\/griddb.net\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/","url":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/griddb.net\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/4fe914ca9576878e82f5e8dd3ba52233","name":"griddb-admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/griddb.net\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5bceca1cafc06886a7ba873e2f0a28011a1176c4dea59709f735b63ae30d0342?s=96&d=mm&r=g","caption":"griddb-admin"},"url":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/author\/griddb-admin\/"}]}},"_links":{"self":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46627","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/comments?post=46627"}],"version-history":[{"count":1,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46627\/revisions"}],"predecessor-version":[{"id":51303,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/posts\/46627\/revisions\/51303"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media\/27179"}],"wp:attachment":[{"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/media?parent=46627"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/categories?post=46627"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/griddb-linux-hte8hndjf8cka8ht.westus-01.azurewebsites.net\/en\/wp-json\/wp\/v2\/tags?post=46627"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}