Postgres Convert Text array to Int array - arrays

In order to use Unnest function I want convert a list to array.
This is my list of type text. It's an output of this function (How get all positions in a field in PostgreSQL?):
108,109,110,114,115,116,117,156,157,200,201,205
I convert to array with
array[108,109,110,114,115,116,117,156,157,200,201,205]
result is type text[]:
"{"108,109,110,114,115,116,117,156,157,200,201,205"}"
With this kind of array unnest function doesn't work so I think I want convert to array of Int
Thanks

with the_data(str) as (
select '108,109,110,114,115,116,117,156,157,200,201,205'::text
)
select elem
from the_data,
unnest(string_to_array(str, ',')) elem;
elem
------
108
109
110
114
115
116
117
156
157
200
201
205
(12 rows)

If I correctly understand, you need this (no necessary convert to INT):
select unnest( string_to_array('108,109,110,114,115,116,117,156,157,200,201,205', ',' ) )

Related

How is an array sliced?

I have some sample code where the array is sliced as follows:
A = X(:,2:300)
What does this mean about the slice of the array?
: stands for 'all' if used by itself and 2:300 gives an array of integers from 2 to 300 with a spacing of 1 (1 is implicit) in MATLAB. 2:300 is the same as 2:1:300 and you can even use any spacing you wish, for example 2:37:300 (result: [2 39 76 113 150 187 224 261 298]) to generate equally spaced numbers.
Your statement says - select every row of the matrix A and columns 2 to 300. Suggested reading

Getting the array sorted in relation to a value Matlab

Let's say I have an array arr of doubles:
arr = 120,121,118,119,117,123,120
And a value x
x = 120
I want to get this value
newarr = 120,120,119,121,118,117,123
Which is a new array, the same size of arr, but the values are sorted in relation to the value x, having the closest value first (doesn't matter if it's ascending or descending).
Any idea?
One approach -
[~,idx] = sort(abs(x-arr))
out = arr(idx)
Output -
out =
120 120 121 119 118 117 123
Since, 191 & 121 are equidistant from x = 120, the output values appear to be different than the ones listed in the expected output of the problem. In this approach, when two such equidistant values appear in arr, the ones appearing at the start are put at the start in the output array too, thus the order of elements is maintained or it's stable in the output array. As, an example to demonstrate this "stability", here's a sample run with modified arr and keeping x the same at 120 -
>> arr
arr =
120 121 118 119 117 123 121 119
>> out
out =
120 121 119 121 119 118 117 123
Note: If you would like to have an ascending order for the equidistant elements, you can first sort arr and then use this approach.

NUMERIC and VARCHAR

I am using SQL Server 2008 R2 to run queries and I have come across a database where it stores numeric values as varchar(4). For example:
SELECT [num]
FROM [TABLE1]
WHERE num > '95'
I get the below results
96
97
98
99
999
However when I run the same query without the '' i.e.
SELECT [num]
FROM [TABLE1]
WHERE num > 95
then I get
100
101
102
103
104
105
106
107
108
109
110
111
112
113
116
117
120
7001
7002
7003
7004
7005
7006
7007
96
97
98
99
999
In any case, I am not getting numbers in order i.e. 95, 96, 97, 98, 99. I understand this is because they are stored as varchar(4) i.e. of a string format. Please can someone explain what happens in both situations and how does a string compare in both the above cases?
Also if someone can help me write the code to change these varchar(4) into numeric on the fly so I can arrange them properly?
Much appreciated.
When you use > '95' it compares the "numbers" in alphabetical order, that's why the result is like that. When you use > 95 it type casts the column into a number and that's why the different result.
To be sure what actually happens, you should do the casting yourself. And of course you should not store numbers as varchars.
The correct ordering would be with
order by convert(int, num)
but it will fail if there's non-numeric fields in the table.
The > does a lexicographical comparison on strings, not numbers. So the output is in order of a string (order by ASC).

How to store the Centroid values of blobs in one Array?

My picture has a certain number of various shapes of blobs. I want to store those centroid values in one array for the future use. So I tried the following code, but it did not work. So can anyone help me?
Sample:
for i = 1:length(STATS)
centroid = STATS(i).Centroid;
array = zeros(length(STATS));
array(i) = centroid;
end
I want to store the centroid data in one array like below
array=
145 145
14 235
145 544
14 69
74 55
Try the following:
for i = 1:length(STATS)
array{i} = STATS(i).Centroid;
end
You can print the entire array using the following:
array{:}
You can read more about cell arrays here. Also, in your older code, you were trying to assign an array (Centroid) to an element of an array(array(i)).
How about:
array=cell2mat({STATS.Centroid});
Assuming
STATS(1).Centroid = [145 145];
STATS(2).Centroid = [14 235]; % Etc...
Try:
array = reshape([STATS.Centroid],2,size(STATS,2))'
array =
145 145
14 235
145 544
14 69
74 55
How this works:
[STATS.Centroid] is a short version of [STATS(1).Centroid, STATS(2).Centroid, .. STATS(n).Centroid]. This will give you the values as a vector. reshape is then used to make it into your desired size.

Finding bigram in a location index

I have a table which indexes the locations of words in a bunch of documents.
I want to identify the most common bigrams in the set.
How would you do this in MSSQL 2008?
the table has the following structure:
LocationID -> DocID -> WordID -> Location
I have thought about trying to do some kind of complicated join... and i'm just doing my head in.
Is there a simple way of doing this?
I think I better edit this on monday inorder to bump it up in the questions
Sample Data
LocationID DocID WordID Location
21952 534 27 155
21953 534 109 156
21954 534 4 157
21955 534 45 158
21956 534 37 159
21957 534 110 160
21958 534 70 161
It's been years since I've written SQL, so my syntax may be a bit off; however, I believe the logic is correct.
SELECT CONCAT(i.WordID, "|", j.WordID) as bigram, count(*) as freq
FROM index as i, index as j
WHERE j.Location = i.Location+1 AND
j.DocID = i.DocID
GROUP BY bigram
ORDER BY freq DESC
You can also add the actual word IDs to the select list if that's useful, and add a join to whatever table you've got that dereferences WordID to actual words.

Resources