Extracting specific value from a table - kdb

I have the tabe:
As: 11 43 23 67 76
Bs: 87 38 70 8 10
syms:A`B where 4 4
AA:([] A:As;B:Bs)
1#select A from AA
I get the output
A
--
11
I would like to know how to just have the value returned instead of having the output to be a table? So, in this case, it would just return 11.

One of numerous ways to do this
q)AA[0]`A
11
to get last item
q)last[AA]`A
76
or both at once
q)(first;last)#\:AA`A
11 76

You want to use the exec keyword instead of select when you want column values as a list:
1#exec A from AA

Try using exec instead of select, which will return just the value in a list.
Note: If the query is in a hdb / on a partitioned db then you'll need to select first then exec.

Related

Sequelize: Query with order by a field in JSONB object as number

I have looked into Sequelize: Query with order by a field in JSONB object but still have some bug.
when I sort the query by the json field which have number in it, it will sort it as string, and result will be
1
11
111
2
22
222
3
33
333
Is there any way to sort the query by json field as number like below?
1
2
3
11
22
33
111
222
333
The code I use is like:
models.findAll({
order:[
['json.a','DESC']
]
});
Thanks and sorry for my bad english.
Just cast your extracted data using CAST
select json_id
from mytable
order by CAST ( json_id AS integer )
Demo here

Enums for tables

I found no information about what the enum is over the table domain on https://code.kx.com/q/ref/enumerate/. But something interesting exists there: https://code.kx.com/q/kb/linking-columns. I tried those examples and found an enum structure that behaves in some situations like a normal enum, but has a strange behaviour in others.
q)kt:1!t:([]a:`a`b`c;b:10 20 30)
q)tt:([]k:`a`a`a`b;d:11 21 31 41)
q)show et1:`t!t[`a]?tt[`k]
`t!0 0 0 1
q)show et2:`kt$tt[`k]
`kt$`a`a`a`b
q)meta select k,d,et1,et2 from tt
c | t f a
---| ------
k | s
d | j
et1| j t
et2| s kt
q)select r1.a, r1.b, r2.a, r2.b from update r1:et1, r2:et2 from tt
a b a1 b1
----------
a 10 a 10
a 10 a 10
a 10 a 10
b 20 b 20
From this perspective et1 and et2 both have similar behaviour. But if we check other enum properties, we see differences:
q)et2[0]
`kt$`a
q)et2[0]:`a
q)
q)et1[0]
`t!0
q)et1[0]:0 / neither works this
't
[0] et1[0]:0
^
q)et1[0]:(`a`b!(`a;10)) / nor that
't
[0] et1[0]:(`a`b!(`a;10))
^
The situation seems more weird if we build enums for just a keyed tables: see a difference for a table with one key column and for two:
q)kkt:2!t:([]a:`a`b`c;b:10 20 30;c:11 22 33)
q)kt:1!0!kkt
q)show ekkt:`kkt$((`a;10);(`b;20);(`b;20))
`kkt!0 1 1
q)show ekt:`kt$(`a`b`b)
`kt$`a`b`b
The same hardcoded (with !) enum notation for kkt.
So the question: what are they? - those enums with a familiar $ and with a hardcoded ! notaions for a table? Is it possible to apply enum-extend technique (?) for them and how? And is there any documentation for them?
What you're seeing is the difference between a simple foreign key and a linked column. As mentioned in the documentation, differences include:
a foreign key is specifically designed to link to the keys of a keyed table.
A foreign key does not allow the link if there's an "unknown key" that isn't one of the keys in the keyed table
linked columns can link to any arbitrary column (if even a value doesn't appear in the other table - thus it doesn't guarantee referential integrity)
linked columns are generally used for on-disk tables
q)kt:([eid:1001 1002 1003] name:`Dent`Beeblebrox`Prefect; iq:98 42 126)
q)tdetails2:([] eid:1003 1001 1002 1001 1002 1001 777;sc:126 36 92 39 98 42 7)
q)update linker:`kt!((0!kt)`eid)?eid from `tdetails2
`tdetails2
q)select linker.name from tdetails2
name
----------
Prefect
Dent
Beeblebrox
Dent
Beeblebrox
Dent
The latter would not have been allowed for a simple foreign key.
Also I don't know why you would want to modify /edit the values of an enumeration - don't do that!

Does distinct function apply unique attribute to list in q kdb?

In output of asc function applied on a list, we can see that the output consists of sorted attribute.
q)asc 1 3 11 10 4
`s#1 3 4 10 11
But in the output of distinct function applied on a list, we cannot see unique attribute applied on the list.
q)distinct 1 3 11 10 4
1 3 11 10 4
But, the time taken to search an element in distinct list and unique list(list on which unique attribute is applied) is almost same.
q)n:1000000?1000000
q)d:distinct n
q)\t:100000 d[1021]
45
q)\t:100000 d[632265]
45
q)u:`u#d
q)\t:100000 u[1021]
44
q)\t:100000 u[632265]
48
So, is the distinct function applying unique attribute internally on the list and converting it to hash table?
distinct does not apply unique attribute to list. You may see this with help of attr function
attr distinct 10?10
will return nothing `, when
attr `u#distinct 10?10
returns `u
Also, I think the experiment may be wrong: d[1021] seems to be usual 0(1) time operation of getting element by index. If you use search instead, you'll see the difference (numbers on my PC):
q)\t:10000 d?770751
85
q)\t:10000 u?770751
6

how to pass column name of a table to the table valued function in Oracle 10g?

In a table I have comma separated values and I have to change these values into rows.
Ex: MSGVALUES column
145,24,56,78
23,45,67
Expected output for this
MSGVALUES column
145
24
56
78
23
45
67
I got the above result by using table valued function(CSV) from Google search.
select * from table (CSV('10,20,'34',',')
If I execute CSV function then I am getting the result like
1
20
34
Now my actual requirement is I have to apply the above CSV function to my column name ie.MSG VALUE column. Assume my table name is CODEDESC
so you'd join the table() cast to your table like:
select csv.*
from your_tab t, table(csv(t.msgvalues, ',')) csv;

Postgresql sorting mixed alphanumeric data

Running this query:
select name from folders order by name
returns these results:
alphanumeric
a test
test 20
test 19
test 1
test 10
But I expected:
a test
alphanumeric
test 1
test 10
test 19
test 20
What's wrong here?
You can simply cast name column to bytea data type allowing collate-agnostic ordering:
SELECT name
FROM folders
ORDER BY name::bytea;
Result:
name
--------------
a test
alphanumeric
test 1
test 10
test 19
test 20
(6 rows)
All of this methods sorted my selection in alphabetical order:
test 1
test 10
test 2
test 20
This solution worked for me (lc_collate: 'ru_RU.UTF8'):
SELECT name
FROM folders
ORDER BY SUBSTRING(name FROM '([0-9]+)')::BIGINT ASC, name;
test 1
test 2
test 10
test 20
select * from "public"."directory" where "directoryId" = 17888 order by
COALESCE(SUBSTRING("name" FROM '^(\d+)')::INTEGER, 99999999),
SUBSTRING("name" FROM '[a-zA-z_-]+'),
COALESCE(SUBSTRING("name" FROM '(\d+)$')::INTEGER, 0),
"name";
NOTE: Escape the regex as you need, in some languages, you will have to add one more "\".
In my Postgres DB, name column contains following, when I use simple order by name query:
1
10
2
21
A
A1
A11
A5
B
B2
B22
B3
M 1
M 11
M 2
Result of Query, After I have modified it:
1
2
10
21
A
A1
A5
A11
B
B2
B3
B22
M 1
M 2
M 11
You may be able to manually sort by splitting the text up in case there is trailing numerals, like so:
SELECT * FROM sort_test
ORDER BY SUBSTRING(text FROM '^(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(text FROM ' (\\d+)$')::INTEGER, 0);
This will sort on column text, first by all characters optionally excluding an ending space followed by digits, then by those optional digits.
Worked well in my test.
Update fixed the string-only sorting with a simple coalesce (duh).
OverZealous answer helped me but didn't work if the string in the database begun with numbers followed by additional characters.
The following worked for me:
SELECT name
FROM folders
ORDER BY
COALESCE(SUBSTRING(name FROM '^(\\d+)')::INTEGER, 99999999),
SUBSTRING(name FROM '^\\d* *(.*?)( \\d+)?$'),
COALESCE(SUBSTRING(name FROM ' (\\d+)$')::INTEGER, 0),
name;
So this one:
Extracts the first number in the string, or uses 99999999.
Extracts the string that follows the possible first number.
Extracts a trailing number, or uses 0.
A Vlk's answer above helped me a lot, but it sorted items only by the numeric part, which in my case came second. My data was like (desk 1, desk 2, desk 3 ...) a string part, a space and a numeric part. The syntax in A Vlk's answer returned the data sorted by the number, and at that it was the only answer from the above that did the trick. However when the string part was different, (eg desk 3, desk 4, table 1, desk 5...) table 1 would get first from desk 2. I fixed this using the syntax below:
...order by SUBSTRING(name,'\\w+'), SUBSTRINGname FROM '([0-9]+)')::BIGINT ASC;
Tor's last SQL worked for me. However if you are calling this code from php you need add extra slashes.
SELECT name
FROM folders
ORDER BY
COALESCE(SUBSTRING(name FROM '^(\\\\d+)')::INTEGER, 99999999),
SUBSTRING(name FROM '^\\\\d* *(.*?)( \\\\d+)?$'),
COALESCE(SUBSTRING(name FROM ' (\\\\d+)$')::INTEGER, 0),
name;