Pass category object variables into a free hand SQL query
Firstly, and stating the obvious - but make sure that you really really need to use free-hand SQL in your chart.
OK - so your sticking with writing free hand SQL. The good news is that you can still reference [[VARIBALES]] and {{Object}} selections in the SQL.
Use a [[VARIABLE]]
You can reference a [[VARIABLE]] anywhere in your SQL. You need to decide whether you need to use '' quotes , i.e. dates / strings, or no quotes if it is a number.
So I want to limit sales in free hand sql based on sales dates.
In the edit chart screen as above - you will see your [[VARIABLE]] placeholder. However, if you save the chart and view the SQL in situ then you will see how the final SQL replacement looks, and exactly what has been executed on the DB.
[[VARIABLE]] replacement can take place in any part of the query.
{{Object}} replacement in SQL.
In my Example I now add three category objects.
You will notice that these do not apply to your free hand SQL elements. Are you still sure you want to use Free Hand SQL??.
The good news is though, that as with [[VARIABLES]] we can apply in the SQL itself.
So if I want region to apply I do the following;
If I look at the executed SQL I will see it is changed when I change the drop list value.
This is Good - but I get a problem if nothing is selected in the droplist.
When -All- is selected in the droplist then the {{object}} reference is not replaced in the SQL.
Fixing All selections
I can fix the problem above by introducing an OR clause. This is how I do this, others may have other strategies for this.
When All is selected the generated SQL looks like
So now the OR part of the query is enacted when All is selected and I see all regions.
Wow that’s complicated - Yes it is / are you still sure you want to use free hand SQL? Pi handles all of this very elegantly for you when you don’t use free hand SQL.
Multi-picker
The {{object}} solution above is fine for the above but when you use a Multipicker you will see a list seperated by ::::
But you’ll get no data because the SQL becomes.
Now you may need to google your DB’s sql syntax here - as it could be different to my (MySQL) solution here.
Then the SQL resolves to
I can combine this with a element to cope when the user makes no selection.
SELECT
sum(nr_sales.QUANTITY) AS Y0,
nr_sales.PAYMENT_METHOD AS X0
FROM
retail.nr_sales nr_sales
JOIN retail.nr_stores nr_stores ON nr_sales.STORE_ID = nr_stores.STORE_ID
WHERE
(FIND_IN_SET(nr_stores.STORE_MANAGER , REPLACE('{{Store Manager}}', '::::', ',')) OR '{{Store Manager}}' LIKE '%{Store Manager}}')
GROUP BY
nr_sales.PAYMENT_METHOD
ORDER BY
nr_sales.PAYMENT_METHOD
In your db - you can find your syntax from the web / your favourite LLM
i.e.
Handling a Between (Dates)
There are two values in a date range
You can find them by select the {{object[0]}} and {{object[1]}}
So Our SQL becomes
When executed it will look like
Note that the date is in a strange format - this is what the browser returns! - so we need to decode our date.
(DATE_FORMAT(nr_sales.SALE_DATE, '%d %M %Y') BETWEEN '{{Sale Date[0]}}' AND '{{Sale Date[1]}}')
NOTE: some browsers return Sep (September) as Sept. So everything is 3 chars except Sept.
So you may even need to
(DATE_FORMAT(nr_sales.SALE_DATE, '%d %M %Y')
BETWEEN REPLACE('{{Sale Date[0]}}','Sept','Sep') AND REPLACE('{{Sale Date[1]}}'),'Sept','Sep')
Wow that’s complicated - Yes it is / are you still sure you want to use free hand SQL? Pi handles all of this very elegantly for you when you don’t use free hand SQL.
FREE HAND SQL SHOULD BE A LAST RESORT
Putting it all together.
So the SQL that does everything above looks like.
SELECT
sum(nr_sales.QUANTITY) AS Y0,
nr_sales.PAYMENT_METHOD AS X0
FROM
retail.nr_sales nr_sales
JOIN retail.nr_stores nr_stores ON nr_sales.STORE_ID = nr_stores.STORE_ID
WHERE
(nr_stores.REGION = '{{Region}}' OR '{{Region}}' LIKE '%{Region}}')
AND
(FIND_IN_SET(nr_stores.STORE_MANAGER , REPLACE('{{Store Manager}}', '::::', ',')) OR '{{Store Manager}}' LIKE '%{Store Manager}}')
AND
(DATE_FORMAT(nr_sales.SALE_DATE, '%d %M %Y') BETWEEN '{{Sale Date[0]}}' AND '{{Sale Date[1]}}' OR '{{Sale Date[0]}}' LIKE '%{Sale Date[0]}}')
AND
(DATE_FORMAT(nr_sales.SALE_DATE, '%d %M %Y') < '[[TODAY]]')
GROUP BY
nr_sales.PAYMENT_METHOD
ORDER BY
nr_sales.PAYMENT_METHOD
CUSTOMER NEWS - Our November 24 Release Is Now Available - Download It Now!