How do I query a PostgreSQL JSON column for a specific type of value? - postgresql

I have a table responses which has a JSON column value. The value column should be an array of text values, like so:
["Value One", "Value Two", "Value Three"]
However, a bug in the associated application resulted in some of these values being saved as a string, like:
"Value One"
Is there a way to query this column for only text/string types so I can address the bad entries?

Use the function jsonb_typeof(), e.g.:
with responses(value) as (
values
('["Value One", "Value Two", "Value Three"]'::jsonb),
('"Value One"')
)
select *
from responses
where jsonb_typeof(value) <> 'array'
value
-------------
"Value One"
(1 row)

Related

How can I compare json field with a string value in postgresql?

I have a field payload saved in a postgresql table which is json type. This type has a nested field subcategory which is string. Below is the output of this value:
=> select payload->'subcategory' from "Merchant";
?column?
-------------------------------
"Food"
null
"AUTOMOTIVE"
null
"MEDICAL"
null
null
"CLUB"
"Petrol Stations"
However, I can't put this field in the where clause. Below query returns 0 rows. But from above output it shows there are rows whose value is CLUB. What is the right way to use json field in where clause?
=> select count(*) from "Merchant" where ("payload"->'subcategory')::text = 'CLUB';
count
-------
0
Figured out what's wrong, I need to use ->> in the where like "payload"->'subcategory'.
that because ->> converts it to text while -> makes it as JSONB
An alternative solution is to use the JSON contains operator #>:
select count(*)
from "Merchant"
where payload #> '{"subcategory": "CLUB")';

jsonb_set deep nested update error occurs says No function matches the given name and argument types

Get the nested object.
select jdoc -> 'members' ->'coach' from api where id = 22;
returns :
{"id": 11, "name": "A dude"}
trying to update nested object, but failed.
update api set jdoc = jsonb_set(jdoc, '{members,coach,id}', 21) where id = 22;
Error:
No function matches the given name and argument types. You might need to add explicit type casts.
So where did I went wrong? jdoc column obviously is an jsonb column.
Manual reference: select jsonb_set('[{"f1":1,"f2":null},2,null,3]'::jsonb, '{0,f1}', '[2,3,4]', false)
The third parameter needs to be a JSONB value:
jsonb_set(jdoc, '{members,coach,id}', to_jsonb(21))

PowerBI-How to use a date table in a dataset with date columns or change a shape map data selecting another columns in the same table

I have added a CSV file in PowerBi with this structure:
In each mau_audience column I have values for different dates for each country in the table.
In the report I have a shape map like this:
I'm trying to change the data on this map inside the report, selecting each mau_audience column, I am a beginner in PowerBi, and I have already tried to create a date table for this table without success.
I expect to be able to select a different mau_audience column to visualize the different values in the map.
Any help or guidance will be very appreciated.
Your source data has no date value. Each column is considered separately.
You can edit your query to unpivot your source data, and calculate a date from the header names:
let
Source = Csv.Document(File.Contents("C:\temp\south_america_data.csv"),[Delimiter=",", Columns=10]),
ReportYear = "2018",
#"Promoted Headers" = Table.PromoteHeaders(Source, [PromoteAllScalars=true]),
#"Unpivoted Other Columns" = Table.UnpivotOtherColumns(#"Promoted Headers", {"admin"}, "Attribute", "Value"),
#"Changed Type" = Table.TransformColumnTypes(#"Unpivoted Other Columns",{{"Value", type number}}),
#"Split Column by Delimiter" = Table.SplitColumn(#"Changed Type", "Attribute", Splitter.SplitTextByEachDelimiter({"_"}, QuoteStyle.Csv, true), {"Field", "Date"}),
#"Split Column by Position" = Table.SplitColumn(#"Split Column by Delimiter", "Date", Splitter.SplitTextByPositions({0, 3}, false), {"Month Name", "Day"}),
#"Inserted Merged Column" = Table.AddColumn(#"Split Column by Position", "Date", each Date.FromText(Text.Combine({[Day], [Month Name], ReportYear}, " ")), type date),
#"Removed Columns" = Table.RemoveColumns(#"Inserted Merged Column",{"Month Name", "Day"}),
#"Pivoted Column" = Table.Pivot(#"Removed Columns", List.Distinct(#"Removed Columns"[Field]), "Field", "Value", List.Sum)
in
#"Pivoted Column"
Now you can create a relationship to your Date table, and build a measure based on the single mau_audience column.

Merging Columns with null values PowerQuery

I have:
Name Value
A null
B null
null 5
null 10
and I need:
Name Value
A 5
B 10
Thanks a lot for providing a solution.
I had asked a similar question, to which #MarcelBeug provided a very helpful response; which, in turn, I'm using as the basis for my answer to you for your specific table.
This requires you to use Power Query (Power BI's query editor).
For your situation, I...
added a column named "Group", with the word "Group" in every one of its rows
then I used "Group By" on that new Group column, using sum aggregation for both the Name and Value columns
then I edited the code that was generated in step 2...changing the occurences of List.Sum to List.RemoveNulls
then I added a column with an embedded table from the two lists that resulted from step 3
then I deleted all columns other than the Tabled column
then I expanded the Tabled column, which gave me this:
Here's the M code:
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Changed Type" = Table.TransformColumnTypes(Source,{{"Name", type text}, {"Value", Int64.Type}}),
#"Added Custom" = Table.AddColumn(#"Changed Type", "Group", each "Group"),
#"Grouped Rows" = Table.Group(#"Added Custom", {"Group"}, {{"NameList", each List.RemoveNulls([Name]), type text}, {"ValueList", each List.RemoveNulls([Value]), type number}}),
#"Added Custom.1" = Table.AddColumn(#"Grouped Rows", "Tabled", each Table.FromColumns({[NameList],[ValueList]},{"Name","Value"})),
#"Removed Other Columns" = Table.SelectColumns(#"Added Custom.1",{"Tabled"}),
#"Expanded Tabled" = Table.ExpandTableColumn(#"Removed Other Columns", "Tabled", {"Name", "Value"}, {"Name", "Value"})
in
#"Expanded Tabled"

How to search in SphinxQL by sql_attr_multi field

This is my query to sphinxQL:
SELECT option_id FROM items WHERE cat IN (10,11) GROUP BY option_id LIMIT 100000 OPTION max_matches=100000
cat is sql_attr_multi field, this query not return to me correct result. Anybody knows how to search by fields by this sphinx attribute?
That query looks for items where cat attribute contains either 10 OR 11, is that what you trying to do?
If its not, would help to know what you are trying to query!
I had similar problem.
When I pass array to IN condition for MVA attribute I have no result, however there is several ones in index.
When I debug condition (attribute array(10, 11) in you case) I see that array values is string integer instead.
array(
0 => "10",
1 => "11"
)
For every single value in condition uses quoteArr() function
https://github.com/FoolCode/SphinxQL-Query-Builder/blob/master/src/SphinxQL.php#L518
wich escape value according with https://github.com/FoolCode/SphinxQL-Query-Builder/blob/master/src/Drivers/ConnectionBase.php#L95
The quote function use is_int() PHP internal function:
$a = "1";
var_dump(is_int($a)); // return bool(false)
It mean, thet instead
cat IN (10, 11)
you have
cat IN ("10", "11")
But sphinx can't filter MVA attribute by not integer (string) values no metter IN or OR WHERE notation you use.
[1064] index document : unsupported filter type 'string' on MVA column [ SELECT * FROM `document` WHERE MATCH('(some query)') AND `_category` = '5' LIMIT 0, 10]
You should use strict value type:
foreach ($category as &$item) {
$item = (int)$item;
} unset($item);
I am not sure that it is your incindent. Unfortunately, there isn't enough data to say it for sure in this case.