How to extract json array elements in postgresql - arrays

What I want to do is sum 29.0 and 34.65 and group by P_id
Table: transaction_items
Column name: Debits, P_id
Column data type: text, text
Data:
Debits
[{"amount":29.0,"description":"Fee_Type_1"}
[{"amount":"34.65","description":"Fee_Type_1"}
P_id
16
16
I tried using the solution mentioned here [https://stackoverflow.com/questions/27834482/how-to-get-elements-from-json-array-in-postgresql][1]
select     transaction_line_items.P_id,
           each_attribute ->> 'amount' Rev
from       transaction_line_items
cross join json_array_elements(to_json(Debits)) each_section
cross join json_array_elements(each_section -> 'attributes') each_attribute
where      (each_attribute -> 'amount') is not null;
However, I got an error saying "cannot deconstruct a scalar".
Can someone please let me know how to parse the values I am looking for?
Thank you.

It seems that your data is broken. The values of Debits column are not valid json due to the lack of right square brackets. Assuming that your data should look like this:
[{"amount":29.0,"description":"Fee_Type_1"}]
[{"amount":"34.65","description":"Fee_Type_1"}]
the following query does what you want:
select p_id, sum(amount)
from (
select p_id, (elements->>'amount')::numeric amount
from transaction_items
cross join json_array_elements(debits::json) elements
) sub
group by p_id;

Related

Count the number of multiple values in a single column in SQL

I have a long list of string values that I would like to count, in one particular column of a table. I know this works for counting all unique values.
SELECT
code_id ,
COUNT(*) AS num
FROM
mydb
GROUP BY
code_id
ORDER BY
code_id
I only have a certain selection of values to count, therefore do now want all. My list is long, but for example, if I just wanted to count the numbers of strings 'ax1', 'c39', and 'x1a' in my code_id column? I've seen examples with multiple lines of code, one for each value which will be huge for counting many values. I'm hoping for something like :
SELECT
code_id ,
COUNT(* = ('ax1, 'c39', 'x1a')) AS num
FROM
mydb
GROUP BY
code_id
ORDER BY
code_id
Desired output would be
code_id count
ax1 39
c39 42
x1a 0
Is there an easy way, rather than a line of code for each value to be counted?
Create a CTE that returns all the string values and a LEFT join to your table to aggregate:
WITH cte AS (SELECT code_id FROM (VALUES ('ax1'), ('c39'), ('x1a')) c(code_id))
SELECT c.code_id,
COUNT(t.code_id) AS num
FROM cte c LEFT JOIN tablename t
ON t.code_id = c.code_id
GROUP BY c.code_id;
See the demo.
I think this should work.
SELECT
code_id ,
sum(1) AS num
FROM Mydb
WHERE code_id in ('ax1', 'c39', 'x1a')
GROUP BY code_id
ORDER BY code_id

Subquery in snowflake with unknown matches, matches to columns

I have a few tables that I'm joining and one of them can have an unknown number of matches, up to 6. Each match should be returned as a row value in the initial query. For example:
SELECT a.ID, a.match1, a.match2, a.match3, a.match4, a.match5, a.match6
FROM table1 a, (SELECT ID, match FROM table2 WHERE a.ID = table2.ID) b
WHERE a.ID = b.ID
That's probably not the right syntax but hopefully it shows what I need. So the nested query MAY return 1 match or 5. Each match should be the value for the corresponding column name, ie a.match1 = first match, b.match2 = second match, etc etc.
Please let me know if I need to explain further. I know this isn't the optimal schema to use but it's what I was told to work with.
Something that SQL doesn't like is an unknown number of columns.
As a quick hack, you could aggregate all matches in an array, and then have a query around it transforming the matches into a predefined (large) number of columns.
Like this:
with data as (
select $1 id
from (values(1),(2))
), data2 as (
select $1 id, $2 match
from (values(1, 'a1'),(1, 'a2'),(2, 'b1'),(2, 'b2'),(2, 'b3'))
)
select id, matches[0], matches[1], matches[2], matches[3]
from (
select a.id, array_agg(match) matches
from data a
join data2 b
on a.id=b.id
group by 1
);

BigQuery - Values referenced in UNNEST must be arrays. UNNEST contains expression of type STRUCT ... at [5:18]

Hello guys this time I came across a new error to group array, I will share with you the schema of the table I am consulting so you can tell me the solution. I tried to use ARRAY_TO_STRING but in this case it didn't work out ...
SELECT
individual_details.gender AS gender,
COUNT(DISTINCT profile.owner_id ) AS profile_count_distinct
FROM dataset.profile AS profile
LEFT JOIN UNNEST(profile.individual_details) as individual_details
GROUP BY 1
ORDER BY 2 DESC
Values referenced in UNNEST must be arrays. UNNEST contains expression
of type STRUCT at [5:18]
individual_details is not an ARRAY, but rather STRUCT - so you do not need UNNEST it
Try below
SELECT
individual_details.gender AS gender,
COUNT(DISTINCT profile.owner_id ) AS profile_count_distinct
FROM dataset.profile AS profile
GROUP BY 1
ORDER BY 2 DESC

Postgres - Cannot Join Json Array Values on UUID

So I have one table Profession:
UUID UUID,
Name TEXT
Where UUID is uuid1, uuid2, uuid3, etc.
Then another table Degrees:
DegreeName TEXT,
Record JSON
Where the Record->'Professions' json record may contain a list of Profession.uuid, such as {"Professions":"[uuid1,uuid2]"}, though the field could be NULL such as {"Professions":"[]"}.
Here is how I am trying to join the two tables:
SELECT prof.uuid, prof.Name, d.DegreeName
FROM Profession prof
LEFT JOIN (
SELECT DegreeName, json_array_elements(Record->'Professions') prof_uuid
FROM Degrees
) d
ON d.prof_uuid::TEXT=prof.uuid::TEXT
When I do this, I only get Nulls. Note that I cast to TEXT because I cannot cast the Professions array to a UUID because of blanks.
I have tried manually searching for the Profession table using a value from the Professions list and it works:
SELECT *
FROM Profession
WHERE uuid = 'someprofuuid'
Is there some cast I missing?
I figured it out. The problem was I was using json_array_elements instead of json_array_elements_text. When I switched that, the join worked:
SELECT prof.uuid, prof.Name, d.DegreeName
FROM Profession prof
LEFT JOIN (
SELECT DegreeName, json_array_elements_text(Record->'Professions') prof_uuid
FROM Degrees
) d
ON d.prof_uuid::TEXT=prof.uuid::TEXT

Substract 2 columns from postgreSQL LEFT JOIN query with NULL values

I have a postgreSQL query which should be the actual stock of samples on our lab.
The initial samples are taken from a table (tblStudies), but then there are 2 tables to look for to decrease the amount of samples.
So I made a union query for those 2 tables, and then matched the uniun query with the tblStudies to calculate the actual stock.
But the union query only gives values when there is a decrease in samples.
So when the study still has it's initial samples, the value isn't returned.
I figured out I should use a JOIN operation, but then I have NULL values for my study with initial samples.
Here is how far I got, any help please?
SELECT
"tblStudies"."Studie_ID", "SamplesWeggezet", c."Stalen_gebruikt", "SamplesWeggezet" - c."Stalen_gebruikt" as "Stock"
FROM
"Stability"."tblStudies"
LEFT JOIN
(
SELECT b."Studie_ID",sum(b."Stalen_gebruikt") as "Stalen_gebruikt"
FROM (
SELECT "tblAnalyses"."Studie_ID", sum("tblAnalyses"."Aant_stalen_gebruikt") AS "Stalen_gebruikt"
FROM "Stability"."tblAnalyses"
GROUP BY "tblAnalyses"."Studie_ID"
UNION
SELECT "tblStalenUitKamer"."Studie_ID", sum("tblStalenUitKamer".aant_stalen) AS "stalen_gebruikt"
FROM "Stability"."tblStalenUitKamer"
GROUP BY "tblStalenUitKamer"."Studie_ID"
) b
GROUP BY b."Studie_ID"
) c ON "tblStudies"."Studie_ID" = c."Studie_ID"
Because you're doing a LEFT JOIN to the inline query "C" some values of c."stalen_gebruikt" can be null. And any number - null is going to yield null. To address this we can use coalesce
So change
"samplesweggezet" - c."stalen_gebruikt" AS "Stock
to
"samplesweggezet" - COALESCE(c."stalen_gebruikt",0) AS "Stock

Resources