Aggregate a boolean array in a LEFT JOIN LATERAL in Postgres - postgresql

Question
How can I achieve aggregation of the boolean array in the LEFT JOIN LATERAL?
A result can have many owners.
There can only by one ownership record that is original - that's because we are supporting the assignment of a result by the original owner to a new owner.
In this case, we would have two ownership records, differing in the owner_id as well as the original boolean value of the row.
ERD
Note: There is a small error in this ERD. The owners table has id INT and owner UUID (not just a single id column). This probably doesn't contribute to the issue - but it does make the SQL a little more gnarly than it should be.
Results
guid
assigned
061c840a-f8d2-4200-8d17-40b35650de40
{true}
074e3e67-c22a-4681-a5da-844b943a0cf9
"{false,true}"
084de451-6531-4997-b788-17819f29a6cb
{true}
Desired Results
guid
assigned
061c840a-f8d2-4200-8d17-40b35650de40
true
074e3e67-c22a-4681-a5da-844b943a0cf9
false
084de451-6531-4997-b788-17819f29a6cb
true
SQL
SELECT DISTINCT ON (results.id) results.id as guid,
assigned
FROM results
LEFT JOIN LATERAL ( SELECT *,
(SELECT array(SELECT ownership.original
FROM ownership
where ownership.result_id = results.id)) as assigned
FROM (ownership
LEFT JOIN owners on (ownership.owner_id = owners.id))) as resultOwnership
ON results.id = resultOwnership.result_id
WHERE resultOwnership.owner = '2a09be27-3fed-4c48-9c63-6877dddc95f5';

Related

How can I restrict a result to only include rows where one specific field is unique with UNION Select statement in BigQuery?

I have the following code. I try to stitch the two tables together, but restrict it to only add duplicate Opportunity_ID once, and then from the second table (OpportunitiesUpdates).
SELECT
Opportunity.Account_Name,
Opportunity.Opportunity_Name,
Opportunity.Opportunity_Owner,
Opportunity.Opportunity_ID
FROM
Opportunity
UNION DISTINCT
SELECT
OpportunityUpdates.Account_Name,
OpportunityUpdates.Opportunity_Name,
OpportunityUpdates.Opportunity_Owner,
OpportunityUpdates.Opportunity_ID
FROM
OpportunityUpdates
WHERE OpportunityUpdates.Opportunity_ID <> Opportunity.Opportunity_ID
This code consolidates all records from both tables (by Opportunity_ID) and gives priority to the OpportunityUpdates table based on Opportunity_ID.
It assumes that the same Opportunity_ID could be in either table ("duplicates"), but that within each table an Opportunity_ID is unique. It also assumes that Opportunity_ID is not nullable (never null).
SELECT DISTINCT
IF(ou.Opportunity_ID IS NOT NULL, ou.Account_Name, o.Account_Name) Account_Name,
IF(ou.Opportunity_ID IS NOT NULL, ou.Opportunity_Name, o.Opportunity_Name) Opportunity_Name,
IF(ou.Opportunity_ID IS NOT NULL, ou.Opportunity_Owner, o.Opportunity_Owner) Opportunity_Owner,
COALESCE(ou.Opportunity_ID, o.Opportunity_ID) Opportunity_ID
FROM OpportunityUpdates ou
FULL OUTER JOIN
Opportunity o
ON o.Opportunity_ID = ou.Opportunity_ID

PostGres joins Using JSONB

I have two tables which look like such
Organizations
Id (primary_key. big int)
Name (text)
CustomInformations
Id (primary_key. big int)
ConnectedIdentifiers (JSONB)
Info (text)
CustomInformations's ConnectedIdentifiers column contains a JSONB structure which looks like
{ 'organizations': [1,2,3] }
This means that there's an array of organizations with those ids 1, 2, 3, which are related to that particular CustomInformation
I'm trying to do a JOIN where given a CustomInformation Id will also get me all the Organizations names
I tried this after looking at some examples:
SELECT * FROM CustomInformations ci
INNER JOIN Organizations o on jsonb_array_elements(ci.ConnectedIdentifiers->'19') = o.id
WHERE
ci.id = 5
I got an error No operator matches the given name and argument type(s). You might need to add explicit type casts.
Is this the right approach? And if so what is wrong with my syntax?
Thanks
You cannot use jsonb_array_elements() in this way because the function returns set of rows. It should be placed in a lateral join instead. Use jsonb_array_elements_text() to get array elements as text and cast these elements to bigint:
select ci.*, o.*
from custominfo ci
-- lateral join
cross join jsonb_array_elements_text(ci.connectedidentifiers->'organizations') ar(elem)
join organizations o
on elem::bigint = o.id
where ci.id = 5

How to use GROUP BY with Firebird?

I'm trying create a SELECT with GROUP BY in Firebird but I can't have any success. How could I do this ?
Exception
Can't format message 13:896 -- message file C:\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).
(49,765 sec)
trying
SELECT FA_DATA, FA_CODALUNO, FA_MATERIA, FA_TURMA, FA_QTDFALTA,
ALU_CODIGO, ALU_NOME,
M_CODIGO, M_DESCRICAO,
FT_CODIGO, FT_ANOLETIVO, FT_TURMA
FROM FALTAS Falta
INNER JOIN ALUNOS Aluno ON (Falta.FA_CODALUNO = Aluno.ALU_CODIGO)
INNER JOIN MATERIAS Materia ON (Falta.FA_MATERIA = Materia.M_CODIGO)
INNER JOIN FORMACAOTURMAS Turma ON (Falta.FA_TURMA = Turma.FT_CODIGO)
WHERE (Falta.FA_CODALUNO = 238) AND (Turma.FT_ANOLETIVO = 2015)
GROUP BY Materia.M_CODIGO
Simple use of group by in firebird,group by all columns
select * from T1 t
where t.id in
(SELECT t.id FROM T1 t
INNER JOIN T2 j ON j.id = t.jid
WHERE t.id = 1
GROUP BY t.id)
Using GROUP BY doesn't make sense in your example code. It is only useful when using aggregate functions (+ some other minor uses). In any case, Firebird requires you to specify all columns from the SELECT column list except those with aggregate functions in the GROUP BY clause.
Note that this is more restrictive than the SQL standard, which allows you to leave out functionally dependent columns (ie if you specify a primary key or unique key, you don't need to specify the other columns of that table).
You don't specify why you want to group (because it doesn't make much sense to do it with this query). Maybe instead you want to ORDER BY, or you want the first row for each M_CODIGO.

sql compare two table for different select

I have this two table
One:
ID SystemProductID
E57AD213-3953-481C-BA2B-4AF8B98A87B6 02188530
2471F038-2646-4EC2-B245-4AF919901A71 02000099
3A7D0896-EBB3-4E30-A535-4AF94FE83CCE 02025567
Two:
SystemProductID
02188530
02000099
02460103
02460101
How to select some of that
IsExist SystemProductID ID
true 02188530 E57AD213-3953-481C-BA2B-4AF8B98A87B6
true 02000099 2471F038-2646-4EC2-B245-4AF919901A71
false 02460103 NULL
false 02460101 NULL
Please tell me how to do this
full join is not working on what i want
In my way of thinking, I always use what tables I know will have all of the rows of data and LEFT JOIN from there. I generally don't like RIGHT JOINs as they seem counter-intuitive to me. A FULL JOIN could work as well.
So, we take all the table two's rows and left join on the ID for table one where we can.
SELECT
CASE
WHEN t1.SystemProductID IS NULL THEN 'false'
else 'true'
END [IsExist]
,t2.SystemProductID
,t2.ID
FROM TableTwo t2
LEFT JOIN TableOne t1 ON t1.SystemProductID=t2.SystemProductID

Embedded Select for From value

Having difficulty framing my question for Google.
I am trying to embed a select statement which pulls partition table names from a view. I want to cycle through these tables and do a search within them for a value count.
I have:
SELECT COUNT(objectA)
FROM (SELECT partitiontablename
FROM partitions
WHERE tablename = 'x')
AS tableNameQuery
WHERE objectB = 1
I am getting ERROR: column "objectB" does not exist
The partitions tables do have objectB (they are the same table structure). Can you guide me to what i am doing wrong?
Thank you!
Try this query:
SELECT COUNT(objectA)
FROM (
SELECT partitiontablename, objectB, objectA
FROM partitions
WHERE tablename = 'x'
) AS tableNameQuery
WHERE objectB = 1
The subquery in your query retrieves only partitiontablename column, so the outer query sees only that column, but doesn't see objectB.
The same problem is with objectA used in COUNT() in the outer query.