1

I have a function that does something with a date and a function that takes two arguments to perform a calculation. For now let's assume that they look as follows:

d:{[x] :x.hh}
f:{[x;y] :x+y}

Now I want to use function f in a query as follows:

select f each (columnOne,d[columnTwo]) from myTable

Hence, I first want to convert one column to the corresponding numbers using function d. Then, using both columnOne and the output of d[columnTwo], I want to calculate the outcome of f.

Clearly, the approach above does not work, as it fails with a 'rank error.

I've also tried select f ./: (columnOne,'d[columnTwo]) from myTable, which also doesn't work.

How do I do this? Note that I need to input columnOne and columnTwo into f such that the corresponding rows still match. E.g. input row 1 of columnOne and row 1 of columnTwo simultaneously into f.

1 Answer 1

3

I've also tried select f ./: (columnOne,'d[columnTwo]) from myTable, which also doesn't work.

You're very close with that code. The issue is the d function, in particular the x.hh within function d - the .hh notation doesn't work in this context, and you will need to do `hh$x instead, so d becomes:

d:{[x] :`hh$x}

So making only this change to the above code, we get:

q)d:{[x] :`hh$x}
q)f:{[x;y] :x+y}
q)myTable:([] columnOne:10?5; columnTwo:10?.z.t);
q)update res:f ./: (columnOne,'d[columnTwo]) from myTable
    columnOne columnTwo    res
    --------------------------
    1         21:10:45.900 22
    0         20:23:25.800 20
    2         19:03:52.074 21
    4         00:29:38.945 4
    1         04:30:47.898 5
    2         04:07:38.923 6
    0         06:22:45.093 6
    1         19:06:46.591 20
    1         10:07:47.382 11
    2         00:45:40.134 2

(I've changed select to update so you can see other columns in result table)

Other syntax to achieve the same:

q)update res:f'[columnOne;d columnTwo] from myTable
    columnOne columnTwo    res
    --------------------------
    1         21:10:45.900 22
    0         20:23:25.800 20
    2         19:03:52.074 21
    4         00:29:38.945 4
    1         04:30:47.898 5
    2         04:07:38.923 6
    0         06:22:45.093 6
    1         19:06:46.591 20
    1         10:07:47.382 11
    2         00:45:40.134 2

Only other note worthy point - in the above example, function d is vectorised (works with vector arg), if this wasn't the case, you'd need to change d[columnTwo] to d each columnTwo (or d'[columnTwo])

This would then result in one of the following queries:

select res:f'[columnOne;d'[columnTwo]] from myTable
select res:f ./: (columnOne,'d each columnTwo) from myTable
select res:f ./: (columnOne,'d'[columnTwo]) from myTable
Sign up to request clarification or add additional context in comments.

3 Comments

I will try this out. Actually my real d function does something else. I just made it .hh for this question. But this seems very helpful. Thank you!
Now that I think of it, both my f and d functions are probably not vector based. Hence both need some sort of each as input. How would the syntax work then? Thank you in advance :)
Never mind, I found the syntax myself (I've updated your answer with some example queries). It was the same as you proposed. Thanks again :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.