I know there has to be a way to do this, but my googling was to no avail. I am trying to take a recordset, create an array and sort the elements alphabetically.
How would I accomplish this?
To do this you will need to use the ORDER BY clause in the ARRAY_AGG function.
Example:
SELECT ARRAY_AGG(fullname ORDER BY lastname)
FROM ...
This will return an array with names sorted by last name.
Related
I keep having a problem when filtering some data in postgresql.
For example, I want to filter by a json.
My jsons are saved in the following way
"[{\"Brand\":\"Leebo\"},{\"Housing Color\":\"Black\"},{\"Beam Type\":\"High Beam, Low Beam\"}]"
And let's say that I want to filter after
[{\"Brand\":\"Leebo\"}]
Shouldn't I write something like that in the query?
SELECT * FROM public.products
WHERE attributes is not NULL
AND attributes::text LIKE '%{\"Brand\":\"Leebo\"}%';
I tried also
SELECT * FROM public.products WHERE attributes::jsonb #> '"[{\"Material\":\"Artificial Leather\"}]"'
Because I won't receive data
Do you know how I could proceed differently?
But it only works if the column has all the data (eg if I give the exact data that is in the column)
Also, how could I search with whereIn?
You have an array in your JSONB because those characters ([ and ]) are array characters. If you are sure that you will always have only one array in your JSONB so you can use this:
SELECT * FROM public.products
WHERE attributes is not NULL
AND attributes[0]->>'Brand' = 'Leebo'
But if you can have several arrays inside JSONB then use jsonb_array_elements for extracting array elements, after then you can use JSONB operations like as ->>
I tried using an array of integers, then an array of strings. However, I keep getting the same error:
ERROR: operator does not exist: jsonb ?| integer[]
My query looks like this:
Bet.query()
.select(
'id',
'status'
)
.whereJsonSupersetOf('participants_ids', [userId])
.range()
.limit(10)
.orderBy('id', 'DESC')
.throwIfNotFound();
This is how the arrays are stored:
Each user has a screen where they can see their own bets against another users. In order to list bets for a logged in user, I need to check the participants_ids column. This is an array that contains the ids for the 2 users betting against each other.
The purpose of my query is to return a list of bets where the current user's Id is contained inside each bet's participants_ids array.
Originally, I tried user .where() and .orWhere() to check if the current user's id was either the bet host's id, or the bet challenger's id. This didn't give me the result I wanted though. So I decided an array column would be much better.
I can't seem to get this to work though. I've looked at a few posts, but they seem to be arrays of objects rather than arrays of ints or strings. I simply want to check the participants_ids array column contains the userId I am passing into the query.
I am also using Knex JS.
Any idea what I could be doing wrong here?
Thanks in advance.
.whereJsonXXX methods works only for postgresql jsonb columns.
For querying arrays column types you need to use array operators https://www.postgresql.org/docs/12/functions-array.html
Bet.query()
.select(
'id',
'status'
)
.where('participants_ids', '#>', [userId])
.range()
.limit(10)
.orderBy('id', 'DESC')
.throwIfNotFound();
Or maybe .where('participants_ids', '#>', val([userId]).asArray().castTo('integer[]')) if the array is not passed properly in the first example.
I know that the ATTR function is used for aggregation, but can someone explain it in simple terms?
In the most simplest of terms, ATTR returns a value if it is unique, otherwise it returns "*". I think you'll find this link helpful with examples.
https://www.interworks.com/blog/tcostello/2014/05/15/attr-tableaus-attribute-function-explained
You cannot mix aggregate and non aggregate comparisons in tableau, you have to use ATTR, for e.g. if ATTR(segment) ='Corporate' then sum(sales)
ATTR is like using an already aggregated field for comparison with another aggregated field. Measures are taken as aggregated fields while dimension's aren't. If you have created a field which is already aggregated and still you want to use this field as measure it will be shown as ATTR as it cannot be further aggregated but is behaving like it has.
I tried running this:
db.col.find().skip(5).distinct("field1")
But it throws an error.
How to use them together?
I can use aggregation but results are different:
db.col.aggregate([{$group:{_id:'$field1'}}, {$skip:3},{$sort:{"field1":1}}])
What I want is links in sorted order i.e numbers should come first then capital letters and then small letters.
Distinct method must be run on COLLECTION not on cursor and returns an array. Read this
http://docs.mongodb.org/manual/reference/method/db.collection.distinct/
So you can't use skip after distinct.
May be you should use this query
db.col.aggregate([{$group:{_id:'$field1'}}, {$skip:3},{$sort:{"_id":1}}]) because field field1 will not exists in result after first clause of grouping.
Also I think you should do sort at first and then skip because in your query you skip 3 unsorted results and then sort them.
(If you provide more information about structure of your documents and what output you want it would be more clearly and I will correct answer properly)
I have a field called id (not _id) in documents from two collections. I need to compare the contents of the first collection with the second. Basically, I need to know what documents with a given value 'id' exist in collection 'A', but not 'B'. What's the easiest way to build an array of id's from Collection A that I can use to do something like the following. :
db.B.find({id:{$nin: array_of_ids_from_coll_A}})
Please don't get hung up over why I'm using 'id' in this case, and not '_id'. Thanks.
Strictly speaking, this doesn't answer the question of 'how to build an array that...', but I'd iterate over collection A and, for each element, try to find a match in B. If none is found, add to a list.
This has a lot of roundtrips to the database, so it's not very fast, but it's very simple. Also, if A contains a lot of elements, the array of ids might be too large to throw all of them in the $nin, which otherwise would have to be solved by splitting up the array of ids. To make matters worse, $nin isn't efficient with indexes anyway.
I incorrectly assumed that the function 'distinct' returned a set of distinct documents based on a given 'field'. In fact, it returns an array of distinct values, provided a specific field. So, I was able to construct the array I was looking for with db.A.distinct('id'). Thanks to anyone who took the time to read this question, anyway.