I've discovered that the valuelist() function doesn't like dynamically named queries:
<cfscript>
variables.nNumber = 1;
request.qDirectories = new query();
request.qDirectories.setDBType('query');
request.qDirectories.setAttributes(qDirectories=request.qAllDirectories);
request.qDirectories.setSQL("SELECT id, name, abbr, multiproperties, isPublished,
isArchived, dateAdded, lastModified, lastModifiedBy,
prefix, lstJournalCodes FROM qDirectories");
request["qDirectories#variables.nNumber#"] = request.qDirectories.execute().getResult();
writeDump(valueList(request["qDirectories#variables.nNumber#"].id));
</cfscript>
Upon discovering this, I thought arrayToList() would help. It does help but it only brings back an array with one value in even if there are multiple rows.
Is there a way to get all the values from a particular column in a dynamically named query?
Copying/referencing the dynamic query to a simpler variable name doesn't help? As in:
tempQry= request["qDirectories#variables.nNumber#"];
valueList(tempQry.id);
Related
I am stuck while dynamically forming a new column based certain WHERE clause from another Table in PowerBi. To give more details, let's say I have a table with item numbers associated with a Customer Name. In another table, I have to add a new column, which will dynamically add the item numbers associated with a particular customer and append as a query parameter to a base url.
So, my first table looks like this:
The second table that I want is this:
The query parameter value in the URL, has to be dynamically based on a SELECT query with a WHERE clause and pick up the ItemNumbers using the Customer field which is common between both. So, how can this be done in PowerBi? Any help would be really appreciated :)
I have one table in my model "TableRol" if I want to summarize my Date as the string I can use CONCATENATEX;
URL = CONCATENATE(CONCATENATE("http:\\mysite.com\parametersHere\getitem?='",CONCATENATEX(VALUES('TableRol'[Date]), 'TableRol'[Date],";")),"'")
What would be a correct PowerQuery syntax to extract the information from this Web JSON into a table:
I'm not very familiar with PowerQuery, and this is probably the only time I'll need this, so I'd be grateful if someone would help me out without refering me to documentation. Thanks
[{"time_entry_group": {"minutes": 301,"time_entries_params": {"locked": "0","from": "2021-02-01","to": "2021-02-28","customer_id": "11223344","project_id": "223388","service_id": "435248"},"revenue": 57691.6666666667,"project_id": 223388,"project_name": "Scrb","service_id": 435248,"service_name": "Meetings","month": "202102"}}
, {"time_entry_group": {"minutes": 1175,"time_entries_params": {"locked": "1","from": "2021-01-01","to": "2021-01-31","customer_id": "11223344","project_id": "223388","service_id": "421393"},"revenue": 225208.333333333,"project_id": 223388,"project_name": "Scrb","service_id": 421393,"service_name": "Design","month": "202101"}}
, {"time_entry_group": {"minutes": 24,"time_entries_params": {"locked": "1","from": "2021-01-01","to": "2021-01-31","customer_id": "11223344","project_id": "3168911","service_id": "95033"},"revenue": 4600.0,"project_id": 3168911,"project_name": "youkn Dev","service_id": 95033,"service_name": "Reviews","month": "202101"}}]
For future reference, if you have a column that you need to expand, you can instead click this arrow icon to the right of the column name. Clicking it should display a menu that should then allow you to specify which nested columns you want to get expand or get at. To be clear, it will expand that column for all rows in that table, not just one.
The JSON you've included is basically an array of objects, so maybe use:
Json.Document to parse the JSON, which should give you a list of records
Table.FromRecords to turn the list of records into a table.
Table.ExpandRecordColumn to expand a nested record columns.
Example implementation:
let
json = "[{""time_entry_group"":{""minutes"":301,""time_entries_params"":{""locked"":""0"",""from"":""2021-02-01"",""to"":""2021-02-28"",""customer_id"":""11223344"",""project_id"":""223388"",""service_id"":""435248""},""revenue"":57691.6666666667,""project_id"":223388,""project_name"":""Scrb"",""service_id"":435248,""service_name"":""Meetings"",""month"":""202102""}},{""time_entry_group"":{""minutes"":1175,""time_entries_params"":{""locked"":""1"",""from"":""2021-01-01"",""to"":""2021-01-31"",""customer_id"":""11223344"",""project_id"":""223388"",""service_id"":""421393""},""revenue"":225208.333333333,""project_id"":223388,""project_name"":""Scrb"",""service_id"":421393,""service_name"":""Design"",""month"":""202101""}},{""time_entry_group"":{""minutes"":24,""time_entries_params"":{""locked"":""1"",""from"":""2021-01-01"",""to"":""2021-01-31"",""customer_id"":""11223344"",""project_id"":""3168911"",""service_id"":""95033""},""revenue"":4600,""project_id"":3168911,""project_name"":""youkn Dev"",""service_id"":95033,""service_name"":""Reviews"",""month"":""202101""}}]",
parsed = Json.Document(json),
initialTable = Table.FromRecords(List.Transform(parsed, each [time_entry_group])),
expanded = Table.ExpandRecordColumn(initialTable, "time_entries_params", {"locked", "from", "to", "customer_id"})
in
expanded
One thing about the code above is that it doesn't expand nested fields project_id and service_id (present within time_entries_params). This is because these columns already exist in the table (and having duplicate column names would cause an error). I've assumed this isn't a problem, as the nested values aren't different.
If an object, such as an Array or Struct is used as the column value of a row in a CF query object. Can properties of that object be used in the WHERE clause of a query of queries to limit the result set?
Given:
<cfset local.exampleArray=[
{ id:1,
nestedArray:["Tom","Dick","Harry"],
nestedStruct:{nid:42,name:"unknown"}
},
{ id:2,
nestedArray:["John","Paul","Ringo","George"],
nestedStruct:{nid:12,name:"rockstars"}
},
{ id:3,
nestedArray:["Bonny","Clyde"],
nestedStruct:{nid:43,name:"criminals"}
},
]>
<cfset local.exampleQuery=queryNew("id,nestedArray,nestedStruct","integer,object,object",local.exampleArray)>
The queries of queries:
<cfquery dbtype="query" name="local.exampleQoQ">
SELECT *
FROM [local].exampleQuery
WHERE nestedStruct.nid=12
</cfquery>
<cfquery dbtype="query" name="local.exampleQoQ2">
SELECT *
FROM [local].exampleQuery
WHERE nestedArray.length=3
</cfquery>
Results in the query of queries runtime error:
nestedStruct.nid/nestedArray.length does not match any table in FROM table list
When not using the object type columns in the WHERE clause, the objects are returned correctly when queried and behave as expected:
<cfquery dbtype="query" name="local.exampleQoQ">
SELECT *
FROM [local].exampleQuery
WHERE id=1
</cfquery>
<cfoutput query="local.exampleQoQ">
#local.exampleQoQ.id#:#ArrayLen(local.exampleQoQ.nestedArray)#:#local.exampleQoQ.nestedStruct.nid#
</cfoutput>
Will result in "1:3:42"
Is this just an issue where the QoQ implementation doesn't support accessing the properties of a column value object?
As I mentioned earlier, a database query can have a column with array/structure-ish data, but that's not really what a database is for. As you've seen, it makes querying for the data you want more difficult than it should be, and is really treating a database as little more than a place to store data.
Anyway, you seem to want to filter your query records by a specific value that's contained inside one column's structure data and also filter those results if another columns array data contains a certain number of records.
You don't want Query of Query for this. It's already a highly limited "query" aspect of CF, and should be used only when necessary. If you are using ColdFusion 2016+, you can use a function that was added: queryFilter().
Using your above setup under "Given:", you can use the following:
<cfscript>
/* Instead of QoQ, limit your Query with queryFilter() */
filteredQuery = queryFilter( exampleQuery
,function(o){ return o.nestedStruct.NID == 12 ;
}
) ;
</cfscript>
Which will give you a variable filteredQuery that contains:
Then you can just address filteredQuery.nestedArray to get your array of "John, Paul, George and Ringo".
But you also want to filter for the array in nestedArray to be 3 elements. So you can just add another condition to your callback return:
local.filteredQueryForLength = queryFilter(
local.exampleQuery2,
function(o){ return o.nestedStruct.NID == 12 && arrayLen(o.nestedArray) == 3 ; }
) ;
Which then gives you an empty Query Object, since there are 4 elements to the filteredQuery.nestedArray that you selected.
Finally, queryFilter has a member function that is simply filter(), so you can be even shorter and use this:
local.filteredQueryForLength2 = local.exampleQuery3.filter(
function(o){ return o.nestedStruct.NID == 12 && o.nestedArray.len() == 3 ; }
) ;
Also remember that ColdFusion Query Objects are Pass-By-Reference, so if you do anything (like filter()) that modifies the object, it will change that base object so it will be different if you use it again. Which also means that you don't have to assign it to a variable. You can just call queryFilter and then reference your original query object.
And another note: when using CF Script syntax (which I much prefer), don't forget that=is assignment and==is comparison. I forgot that initially and all of the records were returning withnestedStruct.NIDas12`. :-/
Last note: I created a Fiddle at https://trycf.com/gist/031a090059a46cd471aa44627fc7ee12/acf2016?theme=monokai. I added one extra element to your mocked query, so that you could see what your return object looks like with multiple elements matching the filters.
I have a relatively simple issue, which seems as if it should be achievable, but I have tried absolutely everything with no success.
Here is the situation:
Using Power Query inside Excel I would like to be able to combine multiple queries (lets call these: Query1, Query2 and Query3) into one single query using the Table.Combine function.
The only catch is that the list of queries I will be combining will be dynamic and dependant on another query (lets call this: QueryList)
For example, under certain circumstances QueryList will be:
Query1
Query2
Query3
and under some other condtions QueryList may simply be:
Query1
Query3
What I would like to do is to be able to parse the value of QueryList into the Table.Combine Function:
eg. Table.Combine(#"QueryList")
and thereby allow dynamic consolidation of queries
Whats happening is that I am getting an error that states:
Expression.Error: We cannot convert the value "Query1" to type Table.
Details:
Value=Query1
Type=Type
Update:
I have tried variations of Table.ToList, using { } to create a list, TableFromlist, all with no success (normally errors complain about not being able to comvert from text to list or to table etc.
Thanks in advance for the help.
If your QueryList would be {Query1, Query2} then Table.Combine(QueryList) would work.
Apparently, your QueryList is {"Query1", "Query2"}.
So the strings must be converted to tables, which can be done using Expression.Evaluate. As second parameter, you must supply a record with all possible queries, so the formula becomes, for Query1, Query2, Query3:
= Table.Combine(List.Transform(QueryList, each Expression.Evaluate(_, [Query1 = Query1, Query2 = Query2, Query3 = Query3])))
Is it possible to sort a query object by the length of a varchar column using Query of Queries in ColdFusion?
There is no way to do this entirely with QoQ, no: the QoQ implementation does not provide a len() function. Instead, you could get the database to provide the length data for you.
In the original query add:
len(fieldYouNed) as fieldYouNedLen
In the QoQ then use:
SELECT * FROM query ORDER BY fieldYouNedLen
In Coldfusion 10, you could use the sortBy() function of the Underscore.cfc library like so:
sortedQuery = _.sortBy(queryObject, function(row) {
return len(row.column);
});
(Disclaimer: I created this library)