How can I use a QLIkView set analysis expression in script? - data-analysis

I extend a QLikView application, that has two set analysis expressions used in the visualizations of the app. Now I need to assign the results of the expressions to a variabele but the problem is that the expressions aren't accepted in the script.
My two expressions are :
NUM(SUM({$<Boekjaar = {$(=MAX(Boekjaar))}, PeriodeId = {"<=$(=MAX({<Boekjaar={$(=MAX(Boekjaar))}>} PeriodeId))"}, BalansOmschrijving1 = {"Overzicht kengetallen"}, BalansOmschrijving3 = {"Tussenrekeningen voor BTW"} >} Saldo), '###.###.###.##0')
Num(Sum({$<BalansOmschrijving2 = {"Liquide Middelen"}>} Bedrag * isDebetBoeking) - Sum({$<BalansOmschrijving2 = {"Liquide Middelen"}>} Bedrag * isCreditBoeking),'0,00')
The two tables where the expressions are used :
My goal is to use the expressions in my script and have the possibility to put a value from field JaarMaand into the expressions and calculates 'Saldo liquide middelen' and 'BTW verrekening' belong to the JaarMaand.

Related

mysql query using python 3.6 (string variable is in single quotes)

I am new in python as well as mysql. I am having trouble in populating proper query statement for mysql.
sql = "SELECT * FROM Persons WHERE %s"
cur = db.cursor()
cur.execute(sql,(where,))
where is a string variable which creates a string for WHERE clause; this is the point of question. When I print this variable it give the following result:
Gender = True And IsLate = False
(without any quotes) but when I add this variable to the query to execute it, it adds single quotes around the string.
I used the command
print(cur.statement)
and it prints:
SELECT * FROM Persons WHERE 'Gender = True And IsLate = False'
After supplying parameter, it puts it within single quotes and query returns 0 rows.
I have worked around by concatenating the query statement and variable together and execute the string as query, that worked,
sql = sql + where
cur.execute(sql)
But I know that is not the professional way, as I have searched and found the professional way is to use parameterized query and use variable to store the condition(s) and supplying it at the execution of query.
Looking for advice, am I thinking the right way or otherwise?
The whole point of using parameter substitution in cursor.execute() is that it protects you from SQL injection. Each parameter is treated as a literal value, not substituted into the query and re-interpreted.
If you really want it to be interprted, you need to use string formatting or concatenation, as you discovered. But then you will have to be very careful in validating the input, because the user can supply extra SQL code that you may not have expected, and cause the query to malfunction.
What you should do is build the where string and parameter list dynamically.
where = []
params = []
if gender_supplied:
where.append('gender = %s')
params.append(gender)
if islate_supplied:
where.append*('islate = %s')
params.append(islate)
sql = 'select * from persons'
if where:
query = sql + ' where ' + ' and '.join(where)
else:
query = sql
cur.execute(query, params)

Create a SAS function that takes as input and output a dataset

I am doing the same 10 sub steps transformation to multiple data sets. Let's call this transformation flag_price_change.
This transformation takes as an input a dataset and a threshold (real) and creates 10 subdatasets in order to come up with the final one with some added columns. As I said before, I repeat this transformation to multiple datasets
As I am processing multiple data tables the same way, I would like to know if I could create a function like this in SAS.
flag_price_change(input_table,column_name1,column_name2,threshold,output_table).
Where column_name 1 and 2 are just names of the columns the algorithm just focus on, and output_table should be the created table after the flag_price_change function is executed.
Questions:
What's the procedure to define such a function?
Can I store it in a separate SAS file?
How do I call this function from another SAS program?
SAS functions are for individual observations of data. What you want is a macro (check out a starter guide here), which is defined like this:
%macro flag_price_change(input_table, column_name1, column_name2, threshold, output_table);
/** Inside the macro, you can refer to each parameter/argument
with an ampersand in front of it. So for example, to add
column_name1 to column_name2, you would do the following:
**/
DATA &output_table;
set &input_table;
new_variable = &column_name1 + &column_name2;
RUN;
%mend;
To call the macro, you would do this:
%flag_price_change(
input_table = data1,
column_name1 = var1,
column_name2 = var2,
threshold = 0.5,
output_table = output1);
To call the same code on another data set with different variable names and threshold:
%flag_price_change(
input_table = data2,
column_name1 = var3,
column_name2 = var4,
threshold = 0.25,
output_table = output2);
There are a lot of tricks and catches with macro programming to be aware of, so do check your work at each step.

postgres crosstab query with $libdir/tablefunc crosstab_hash function

My crosstab query (see below) runs just fine. However, I have to generate a large number of such queries, and - crucially - the number of column definitions will vary from day to day. If the number of output columndefs does not match that of the second argument of the crosstab, the crosstab will throw and error and abort. Therefore, I cannot "hard-wire" the column definitions as in my current query, and I need instead a function which will ensure that column definitions will be synchronized on-the-fly. Is it possible to write a generic postgres function that will be reusable in all such instances? Here is my query:
SELECT *
FROM crosstab
('SELECT
to_char(ipstimestamp, ''mon DD HH24h'') As row_name,
ips.objectid::text As category,
COUNT(*)::integer As value
FROM loggingdb_ips_boolean As log
INNER JOIN IpsObjects As ips
ON log.Varid=ips.ObjectId
WHERE (( log.varid = 37551)
OR (log.varid = 27087)
OR (log.varid = 29469)
OR (log.varid = 50876)
OR (log.varid = 45096)
OR (log.varid = 54708)
OR (log.varid = 47475)
OR (log.varid = 54606)
OR (log.varid = 25528)
OR (log.varid = 54729))
GROUP BY to_char(ipstimestamp, ''yyyy MM DD HH24h''), row_name, objectid, category
ORDER BY to_char(ipstimestamp, ''yyyy MM DD HH24h''), row_name, objectid, category',
'SELECT DISTINCT varid
FROM loggingdb_ips_boolean ORDER BY 1;'
)
As CountsPerHour(row_name text,
"25528" integer,
"27087" integer,
"29469" integer,
"37551" integer,
"45096" integer,
"54606" integer,
"54708" integer,
"54729" integer)
PS: Note that this query can be run against test data at the following server:
host: bellariastrasse.com
database: IpsLogging
user: guest
password: guest
I am afraid what you want is not completely possible. If the return type varies, you can either
create a function returning a generic SETOF record.
But then you'd have to provide a column definition list with every call - bringing you right back to where you started.
create a new function with a matching return type for every different case.
But that's what you are trying to avoid ...
If you have to write "a large number of such queries" you could utilize a query-generator function instead, which would not return the results but the DDL script which you would execute in a second step. Basically a function that takes in the variable parts as parameters and generates the query string in your example .. RETURNS text.
This can get pretty complex. Several meta-levels on top of each other have to be considered, but it is absolutely possible. Be sure to make heavy use of dollar-quoting to keep the quoting madness at bay.

Working around LinqToSQls "queries with local collections are not supported" exception

So, I'm trying to return a collection of People whose ID is contained within a locally created collection of ids ( IQueryable)
When I specify "locally created collection", I mean that the Ids collection hasnt come from a LinqToSql query and has been programatically created (based upon user input).
My query looks like this:
var qry = from p in DBContext.People
where Ids.Contains(p.ID)
select p.ID;
This causes the following exception...
"queries with local collections are not supported"
How can I find all the People with an id that is contained within my locally created Ids collection?
Is it possible using LinqToSql?
If Ids is a List, array or similar, L2S will translate into a contains.
If Ids is a IQueryable, just turn it into a list before using it in the query. E.g.:
List<int> listOfIDs = IDs.ToList();
var query =
from st in dc.SomeTable
where listOfIDs.Contains(st.ID)
select .....
I was struggling with this problem also. Solved my problem with using Any() instead
people.Where(x => ids.Any(id => id == x.ID))
As the guys mentioned above, converting the ids, which is of type IQueryable to List or Array will solve the issue, this will be translated to "IN" operator in SQL.But be careful because if the count of ids >= 2100 this will cause another issue which is "The server supports a maximum of 2100 parameters" and that is the maximum number of parameters(values) you can pass to "IN" in SQL server.
Another alternative would be keeping ids as IQueryable and using LINQ "Any" operator instead of "Contains", this will be translated to "EXISTS" in SQL server.
I'm sorry but the answers here didn't work for me as I'm doing dynamic types further along.
What I did was to use "UNION" in a loop which works great. Here's how:
var firstID = cityList.First().id;
var cities = dc.zs_Cities.Where(c => c.id == firstID);
foreach(var c in cityList)
{
var tempCity = c;
cities = cities.Union(dc.zs_Cities.Where(cty => cty.id == tempCity.id));
}

In LINQ to SQL, how do you determine what column elements is a sub-set of another column (i.e. Like-Sql statement)

Here is some code:
//all possible search terms of interest
searchTerms = from s in dc.SearchTerms
select s.term;
//all possible results
var results = from r in dc.Data
select r.hyperlinks;
I want to perform an operation where I get all "r.hyperlinks" that contains s.term.
It is something like r.hyperlinks.Contains(s.term). How can I do this?
It's almost as you wrote it in english:
var results = from r in dc.Data
where searchTerms.Any(x => r.hyperlinks.Contains(x))
select r.hyperlinks;
That's all!
You can put any condition you might come up inside a where clause. Actually, you can put whatever returns a boolean.
Local sequences cannot be used in many LinqToSql operators. But your original question didn't require a local sequence.
var results =
from r in dc.Data
where dc.SearchTerms.Any(s => r.hyperlinks.Contains(s.Term))
select r.hyperlinks;