Select when one of filter-column may not exists

226 Views Asked by At

Suppose a situation when it is not known if a filter column exists.

t:([]a:`s1`s2`s3; c:1 2 3);
select c from t where null t[`a]
select c from t where null t[`b]
'length
(where null t[`a])~where null t[`b]
1b

It column a exists, then the select is ok.

But when I use a filter with column b (not exists) then I get an error.

  1. Why is it happening? - I've checked both of where results - they are the same
  2. How to resolve this situation?
2

There are 2 best solutions below

0
On BEST ANSWER

In QSQL 'where' needs to act on a list of booleans the same length of the table or of count 1. The count of your example is zero

q)t[`b]
`symbol$()
q)count t`b
0

Some examples:

q)select from t where 0b
a c
---
q)select from t where 00b
'length
  [0]  select from t where 00b
       ^
q)select from t where 000b
a c
---
q)select from t where 0000b
'length
  [0]  select from t where 0000b
       ^
q)select from t where 0#0b
'length
  [0]  select from t where 0#0b

Update: Because you mention the results of 'where', where is wrapped in the QSQL format as opposed to acting independently then the result being applied, so you see the below difference

q)where 00b
`long$()
q)select from t where 00b
'length
  [0]  select from t where 00b
       ^
q)select from t `long$()
a c
---
0
On

You can make use of the @ operator to trap the error, so for example

q)@[{select c from t where null t[x]};`b;{x}]
"length"
q)@[{select c from t where null t[x]};`a;{x}]
c
-

although you don't ned to reference columns like this, if you want to dynamically select columns you can use a functional select, so the equivalent query in functional form would be

q)?[`t;enlist(null;`a);0b;(enlist `c)!(enlist `c)]
c
-

the syntax here is quite tricky but the parse keyword is very useful to figure out the argument you should be using so for example

q)parse"select c from t where null a"
?
`t
,,(^:;`a)
0b
(,`c)!,`c

shows you the arguments you need. A combination of error trapping and functional queries should help you out with what you're trying to achieve here.