Joining two tables of data via ID but the ID for one table is 5 more that the other - sql

I'm trying to join two tables of data using ID's. ID's from one table correspond to an ID+5 on the other table.
I've tried using this code:-
SELECT
"Stage",
"Type",
"Contract Type (Business Or Personal)",
"Requested Vehicle",
"Short Vehicle",
"Mileage Per Year",
"Initial Rental",
"Initial Rental £",
"Contract Length",
Opportunities."Advertised Rental",
Contacts.Id,
Opportunities.Id,
"First Name",
"Full Name",
"Email",
"Mobile",
"Phone",
"Contact Owner Name",
Contacts."Lead Source",
Contacts."Created Time"
FROM "Opportunities"
RIGHT JOIN "Contacts" ON Opportunities.Id = Contacts.Id
ORDER BY Contacts."Created Time"
This results in only the contacts data showing up in a table with the opportunities data blank. This is because the ID's are different by 5. So I tried:-
RIGHT JOIN "Contacts" ON Opportunities.Id-5 = Contacts.Id
but that didn't work and I couldn't find anything on the internet that was relevant. Any help would be appreciated as I'm an inexperienced coder.
Thanks,
James

Have you just tried using an alias for a column?
SELECT
"Stage",
"Type",
"Contract Type (Business Or Personal)",
"Requested Vehicle",
"Short Vehicle",
"Mileage Per Year",
"Initial Rental",
"Initial Rental £",
"Contract Length",
Opportunities."Advertised Rental",
Contacts.Id,
Opportunities.Id,
"First Name",
"Full Name",
"Email",
"Mobile",
"Phone",
"Contact Owner Name",
Contacts."Lead Source",
Contacts."Created Time"
FROM (SELECT Opportunities.*, "Id" - 5 AS "ContactId" FROM "Opportunities") AS Opps
RIGHT JOIN "Contacts" ON Opps.ContactId = Contacts.Id
ORDER BY Contacts."Created Time"
Side note, it's probably good to scrub your data to have a cleaner reference than an offset ID if you have permissions to do that.

Related

Snowflake SQL: How to loop through array with JSON objects, to find item that meets condition

Breaking my head on this. In Snowflake my field city_info looks like (for 3 sample records)
[{"name": "age", "content": 35}, {"name": "city", "content": "Chicago"}]
[{"name": "age", "content": 20}, {"name": "city", "content": "Boston"}]
[{"name": "city", "content": "New York"}, {"name": "age", "content": 42}]
I try to extract a column city from this
Chicago
Boston
New York
I tried to flatten this
select *
from lateral flatten(input =>
select city_info::VARIANT as event
from data
)
And from there I can derive the value, but this only allows me to do this for 1 row (so I have to add limit 1 which doesn't makes sense, as I need this for all my rows).
If I try to do it for the 3 rows it tells me subquery returns more than one row.
Any help is appreciated! Chris
You could write it as:
SELECT value:content::string AS city_name
FROM tab,
LATERAL FLATTEN(input => tab.city_info)
WHERE value:name::string = 'city'

SQL query to return nested array of objects in JSON for SQLite

I have 2 simple tables in a SQLite db and a nodejs, express api endpoint that should get results by student and have the subjects as a nested array of objects.
Tables:
Student(id, name) and Subject(id, name, studentId)
This is what I need to result to look like:
{
"id": 1,
"name": "Student name",
"subjects":
[{
"id": 1,
"name": "Subject 1"
},
{
"id": 2,
"name": "Subject 2"
}]
}
How can I write a query to get this result?
If your version of sqlite was built with support for the JSON1 extension, it's easy to generate the JSON from the query itself:
SELECT json_object('id', id, 'name', name
, 'subjects'
, (SELECT json_group_array(json_object('id', subj.id, 'name', subj.name))
FROM subject AS subj
WHERE subj.studentid = stu.id)) AS record
FROM student AS stu
WHERE id = 1;
record
---------------------------------------------------------------------------------------------------
{"id":1,"name":"Student Name","subjects":[{"id":1,"name":"Subject 1"},{"id":2,"name":"Subject 2"}]}
It seems that all you need is a LEFT JOIN statement:
SELECT subject.id, subject.name, student.id, student.name
FROM subject
LEFT JOIN student ON subject.studentId = student.id
ORDER BY student.id;
Then just parse the rows of the response into the object structure you require.

How to query JSON column for unique object values in PostgreSQL

I'm looking to query a table for a distinct list of values in a given JSON column.
In the code snippet below, the Survey_Results table has 3 columns:
Name, Email, and Payload. Payload is the JSON object to I want to query.
Table Name: Survey_Results
Name Email Payload
Ying SmartStuff#gmail.com [
{"fieldName":"Product Name", "Value":"Calculator"},
{"fieldName":"Product Price", "Value":"$54.99"}
]
Kendrick MrTexas#gmail.com [
{"fieldName":"Food Name", "Value":"Texas Toast"},
{"fieldName":"Food Taste", "Value":"Delicious"}
]
Andy WhereTheBass#gmail.com [
{"fieldName":"Band Name", "Value":"MetalHeads"}
{"fieldName":"Valid Member", "Value":"TRUE"}
]
I am looking for a unique list of all fieldNames mentioned.
The ideal answer would be query giving me a list containing "Product Name", "Product Price", "Food Name", "Food Taste", "Band Name", and "Valid Member".
Is something like this possible in Postgres?
Use jsonb_array_elements() in a lateral join:
select distinct value->>'fieldName' as field_name
from survey_results
cross join json_array_elements(payload)
field_name
---------------
Product Name
Valid Member
Food Taste
Product Price
Food Name
Band Name
(6 rows)
How to find distinct Food Name values?
select distinct value->>'Value' as food_name
from survey_results
cross join json_array_elements(payload)
where value->>'fieldName' = 'Food Name'
food_name
-------------
Texas Toast
(1 row)
Db<>fiddle.
Important. Note that the json structure is illogical and thus unnecessarily large and complex. Instead of
[
{"fieldName":"Product Name", "Value":"Calculator"},
{"fieldName":"Product Price", "Value":"$54.99"}
]
use
{"Product Name": "Calculator", "Product Price": "$54.99"}
Open this db<>fiddle to see that proper json structure implies simpler and faster queries.

ActiveRecord Query. Group by multiple columns from multiple tables

Attendance.joins(:user).group(:email, :name).count
The query above gives me the below results. "User 1" had 2 attendances and "User 2" had 6 attendance, plus I have access to the user name and email.
{["email#example.com", "User 1"]=>2, ["email2#example.com", "User 2"]=>6]}
This is great except I'd really like the User.id to be included as well. I can't group by the ID because then each record will be unique instead of being grouped by email and name. The below is what i'd like:
{[1, "email#example.com", "User 1"]=>2, [2, "email2#example.com", "User 2"]=>6]}
Any help would be appreciated.
Answer
Attendance.joins(:user).group(:email, :name, 'attendances.user_id').count
Attendance.joins(:user).group(:email, :name, 'attendances.user_id').count
# collect required fields and group by email, name
grouped_attendance = Attendance.joins(:user).pluck(:id, :email, :name).group_by{|r| [r[1], r[2]]}
# calculate the counts
attendance_counts = grouped_attendance.each{|k,v| grouped_attendance[k] = v.count}
Depending on your setup, but above should be fast enough as you are not instantiating ActiveRecord objects.

Adding an ORDER BY statement to a query without flattening results leads to "Cannot query the cross product of repeated fields"

Query:
"SELECT * FROM [table] ORDER BY id DESC LIMIT 10"
AllowLargeResults = true
FlattenResults = false
table schema:
[
{
"name": "id",
"type": "STRING",
"mode": "NULLABLE"
},
{
"name": "repeated_field_1",
"type": "STRING",
"mode": "REPEATED"
},
{
"name": "repeated_field_2",
"type": "STRING",
"mode": "REPEATED"
}
]
The query "SELECT * FROM [table] LIMIT 10" works just fine. I get this error when I add an order by clause, even though the order by does not mention either repeated field.
Is there any way to make this work?
The ORDER BY clause causes BigQuery to automatically flatten the output of a query, causing your query to attempt to generate a cross product of repeated_field_1 and repeated_field_2.
If you don't care about preserving the repeatedness of the fields, you could explicitly FLATTEN both of them, which will cause your query to generate the cross product that the original query is complaining about.
SELECT *
FROM FLATTEN(FLATTEN([table], repeated_field_1), repeated_field_2)
ORDER BY id DESC
LIMIT 10
Other than that, I don't have a good workaround for your query to both ORDER BY and also output repeated fields.
See also: BigQuery flattens result when selecting into table with GROUP BY even with “noflatten_results” flag on