When !’s left argument is a positive integer, it sets the key fields of a table:

q)flip `a`b`c ! (1 2 3; 1 2 3; 1 2 3)
a b c
—–
1 1 1
2 2 2
3 3 3
q)1! flip `a`b`c ! (1 2 3; 1 2 3; 1 2 3)
a| b c
-| —
1| 1 1
2| 2 2
3| 3 3
q)2! flip`a`b`c ! (1 2 3; 1 2 3; 1 2 3)
a b| c
—| –
1 1| 1
2 2| 2
3 3| 3

When !’s left argument is zero, it returns an unkeyed table from a keyed table:

q)0! ([a: 1 2 3; b: 1 2 3]; c: 1 2 3)
a b c
—–
1 1 1
2 2 2
3 3 3
q)

An arguably more readable equivalent is the xkey function:

q)`a xkey flip `a`b`c ! (1 2 3; 1 2 3; 1 2 3)
a| b c
-| —
1| 1 1
2| 2 2
3| 3 3
q)`a`b xkey flip `a`b`c ! (1 2 3; 1 2 3; 1 2 3)
a b| c
—| –
1 1| 1
2 2| 2
3 3| 3
q)() xkey ([a: 1 2 3; b: 1 2 3]; c: 1 2 3)
a b c
—–
1 1 1
2 2 2
3 3 3
q)

It’s easy to confuse function xkey with key, keys, xcol and xcols.

A virtual column is not stored. There are two kinds of virtual columns in kdb:

  1. The index column, i, which is present in all tables, and
  2. the partition column on a partitioned table. For example, the most common partitioning scheme is by date. Rather than storing the date column along with the other columns in the table, the date is inferred from the partition directory; splayed table directories will not contain files for the date column.

See also: .Q.pf and .Q.pt

q)`Sat`Sun`Mon`Tue`Wed`Thu`Fri .z.D mod 7
`Sat
q)\date
“Sat Mar 5 18:56:04 PST 2011″
q)

see also: -W, .z.D, mod,
\