How do I insert and update array columns in Node-Postgres? - node-postgres

I have the following table in Postgres:
_id: integer, user_id: integer, items: Array
I wish to insert the following into the table:
1, 1, [{productId: 1, size: 'large', quantity: 5}]
Next I wish to update the row with the following:
1, 1, [{productId: 1, size: 'small', quantity: 3}]
How do I do this in node-postgres?
Pseudocode:
update cart
set items.quantity = 3
where cart._id = 1
and cart.items.product_id = 1
and cart.items.size='large'

Related

Postgresql batch update

How to batch update the following sample more efficiently.
users = [{id: 424, pos: 1}, {id: 23, pos: 2}, {id: 55, pos: 3}, ...]
//currently loop updating each {i}:
UPDATE users SET position = i.pos WHERE id = i.id
You can use unnest():
update users u
set position = user.pos
from (values ([{id: 424, pos: 1}, {id: 23, pos: 2}, {id: 55, pos: 3}, ...])
) v(users) cross join lateral
unnest(users) user
where u.id = user.id

Query to filter where value equals #param unless #param is other

I have a filter dropdown list with the following options in it:
1, 2, 3, 4, 5, Other
When the user selects an option I will run a simple SQL query to filter the data by that value such as:
SELECT * FROM Product WHERE Code = #Code
The only problem is that when the "Other" option is selected I need to show everything that does not have a code of 1,2,3,4, or 5.
The data looks like the following:
Id: 1, Name: Product 1, Code: 1
Id: 2, Name: Product 2, Code: 2
Id: 3, Name: Product 3, Code: null
Id: 4, Name: Product 4, Code: 3
Id: 5, Name: Product 5, Code: 12
If the user selects "Other" I need to only display: "Product 3" and "Product 5".
A simple OR condition should accomplish that
SELECT *
FROM Product
WHERE (Code = #Code) OR (#Code = 'Other' AND Code NOT IN (1,2,3,4,5))
Is this what you want?
SELECT *
FROM Product
WHERE (Code = #Code AND #Code IN ('1', '2', '3', '4', '5')) OR
(Code NOT IN ('1', '2', '3', '4', '5') AND #Code = 'Other')
If Code is an integer, then the above may return a type conversion error. In that case, I would recommend:
WHERE Code = TRY_CONVERT(INT, #Code) OR
(Code NOT IN (1, 2, 3, 4, 5) AND #Code = 'Other')

Merge records from two tables

I have two model Part and DamagedPart.
All of them have iid field.
I want to get combined ActiveRecord object with data from these two tables.
Say, parts table has 10 records:
id: 1, iid: 100, d: 0
id: 2, iid: 150, d: 0
id: 3, iid: 200, d: 0
id: 4, iid: 240, d: 0
id: 5, iid: 433, d: 0
...
And damaged_parts table has only two records (for example):
id: 10, iid: 200, d: 4
id: 20, iid: 240, d: 7
Finally I need to get:
id: 1, iid: 100, d: 0
id: 2, iid: 150, d: 0
id: 10, iid: 200, d: 4 # <--- replaced from 'damaged_parts' table
id: 20, iid: 240, d: 7 # <--- replaced from 'damaged_parts' table
id: 5, iid: 433, d: 0
...
Can I get this done by one AR query?
Rails: 4.2.7.1
RDBMS: MariaDB 10.0.27
You need LEFT JOIN and COALESCE
SELECT p.id,
p.iid,
COALESCE(dp.d, p.d) AS d
FROM parts p
LEFT JOIN damaged_parts dp
ON p.id = dp.id
AND p.iid = dp.iid
You can try this.
Part.joins("LEFT OUTER JOIN damaged_parts ON parts.iid = damaged_parts.iid").select("coalesce(damaged_parts.id, parts.id) as id, parts.iid, coalesce(damaged_parts.d, parts.d) as d");
Select FROM parts WHERE iid LIKE'[1-]%';
UNION Select FROM damaged_parts WHERE iid LIKE'[1-]%';

In PostgreSQL, what's the best way to select an object from a JSONB array?

Right now, I have an an array that I'm able to select off a table.
[{"_id": 1, "count: 3},{"_id": 2, "count: 14},{"_id": 3, "count: 5}]
From this, I only need the count for a particular _id. For example, I need the count for
_id: 3
I've read the documentation but I haven't been able to figure out the correct way to get the object.
WITH test_array(data) AS ( VALUES
('[
{"_id": 1, "count": 3},
{"_id": 2, "count": 14},
{"_id": 3, "count": 5}
]'::JSONB)
)
SELECT val->>'count' AS result
FROM
test_array ta,
jsonb_array_elements(ta.data) val
WHERE val #> '{"_id":3}'::JSONB;
Result:
result
--------
5
(1 row)

rethinkdb: secondary compound indexes / aggregation queries and intermediate documents generation

Let's assume such table content where for the same product_id, we have as many rows than updates during status==1 (published) and finally status==0 (unpublished) and then becomes==2 (deleted)
{id: <auto>, product_id: 1, last_updated: 2015-12-1, status: 1, price: 1}
{id: <auto>, product_id: 2, last_updated: 2015-12-1, status: 1, price: 10}
{id: <auto>, product_id: 1, last_updated: 2015-12-2, status: 1, price: 2}
{id: <auto>, product_id: 1, last_updated: 2015-12-3, status: 0, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-2, status: 0, price: 10}
{id: <auto>, product_id: 3, last_updated: 2015-12-2, status: 1, price: 123}
{id: <auto>, product_id: 1, last_updated: 2015-12-4, status: 2, price: 2}
{id: <auto>, product_id: 2, last_updated: 2015-12-4, status: 2, price: 10}
Now, I am trying to find a way, maybe using a secondary compound index, do get for example, given a date like in col1 (using r.time)
DATE STATUS==1 STATUS==0 STATUS==2
2015-12-1 [101, 102] [] []
2015-12-2 [103, 106] [105] []
2015-12-3 [106] [104, 105] []
2015-12-4 [] [] [107, 108]
The difficulty here, is that a product_id document is still to be considered as the most recent status as long as its last_updated date is less or equal to the provided date.
I try by grouping by product_id, then take the max('last_updated'), then only keep each reduction unique document if status==1
I have in mind to have an index for each status / given_date
Or another solution, would be to insert in another table the result of an aggregation which would only store a unique document per date, containing all the initial documents ids matching the same criteria, and so on...
And then later perform joins using these intermediate records to fetch the values of each product_id at the given date/status.
something like:
{
date: <date_object>,
documents: [
{id: document_id, status: 1},
{id: document_id, status: 1},
{id: document_id, status: 2},
{id: document_id, status: 0},
...
]
}
Please advise
Edit 1:
This is an example of a query I try to run to analyse my data, here it is for example to get an overview of the statuses for each group with more than 1 document:
r.db('test').table('products_10k_sample')
.group({index: 'product_id'})
.orderBy(r.desc('last_updated'))
.ungroup()
.map(function(x){
return r.branch(
x('reduction').count().gt(1),
x('reduction').map(function(m){
return [m('last_updated').toISO8601(), m('status'), m('product_id')]
}),
null
)
})