Delete column based on type in KDB+ - kdb

I have a table with a bunch of columns of various types. I need to delete all columns of a particular type, but I can't figure out how to do this.
I would like something like this:
delete from quotes where type = 11
But this doesn't work. Is there a way to do this? I was also able to list the relevant columns with the command
select c from meta quotes where type="s"
But this gives me a one column table with the column headings and I don't know where to go from there.

Could use a functional delete (!), or a take (#) or a drop (_)
q)t:([] col1:`a`b`c;col2:1 2 3;col3:`x`y`z;col4:"foo")
q)![t;();0b;exec c from meta[t] where t="s"]
col2 col4
---------
1 f
2 o
3 o
q)(exec c from meta[t] where t<>"s")#t
col2 col4
---------
1 f
2 o
3 o
q)(exec c from meta[t] where t="s") _ t
col2 col4
---------
1 f
2 o
3 o

Related

KDB: Convert a dictionary of tables into a table?

As per question, I have a dictionary of tables. How do I join the values into a single table?
raze works if the schemas of the tables all conform (aka all columns are the same and in the same order). If they don't conform, a more general option is to union join over:
/tables conform
q)raze `a`b!(([]col1:`x`y;col2:1 2);([]col1:`z`w;col2:3 4))
col1 col2
---------
x 1
y 2
z 3
w 4
/column order different
q)raze `a`b!(([]col1:`x`y;col2:1 2);([]col2:3 4;col1:`z`w))
`col1`col2!(`x;1)
`col1`col2!(`y;2)
`col2`col1!(3;`z)
`col2`col1!(4;`w)
/non-matching columns
q)raze `a`b!(([]col1:`x`y;col2:1 2);([]col2:3 4;col1:`z`w;col3:01b))
`col1`col2!(`x;1)
`col1`col2!(`y;2)
`col2`col1`col3!(3;`z;0b)
`col2`col1`col3!(4;`w;1b)
/uj handles any non-conformity
q)(uj/)`a`b!(([]col1:`x`y;col2:1 2);([]col2:3 4;col1:`z`w;col3:01b))
col1 col2 col3
--------------
x 1 0
y 2 0
z 3 0
w 4 1
Use:
raze x
Raze is defined as:
Return the items of x joined, collapsing one level of nesting.
The table will not include the key, but if the key is also in each table then no information is lost.
It is easy to see what raze does:
parse "raze d"
,/
`d
As a matter of fact, personally in the past I have used the following command to achieve the same output:
(),/ d

How to exclude some records in string in kdb?

I would like to exclude some records from the table.
a:("abc*";"eeee*")
tab:([]cola:("abcdef";"bcdefgh";"tttttt");colb:`a`b`c)
it works if I would like only certain records:
eg.
raze {select from tab where cola like x } each a
output:
cola colb
-------------
"abcdef" a
Now I want to exclude the record above by running the following command
raze {select from tab where not cola like x } each a
But it returns
cola colb
--------------
"bcdefgh" b
"tttttt" c
"abcdef" a
"bcdefgh" b
"tttttt" c
I would like it to return this:
cola colb
--------------
"bcdefgh" b
"tttttt" c
Does this work?
q)select from tab where not any cola like/: a
cola colb
--------------
"bcdefgh" b
"tttttt" c
Edit: Why do we need an any?
If you index into the table with the column name to get the column as an array, it's easier to see:
q)tab[`cola]
"abcdef"
"bcdefgh"
"tttttt"
q)tab[`cola] like/: a
100b
000b
q)any tab[`cola] like/: a
100b
q)not any tab[`cola] like/: a
011b
When you use like with multiple strings and multiple regexes, you will get an array for each string (with the size of the array being the number of regexes). We want to see if our string matches any of the regexes, and then exclude them if they do.

Selecting count of occurences of values in kdb

How to count occurences of distinct values from one column in another column in kdb. The idea is to return the count of values in another column.
The table looks like
Col1 : x,y,z and Col2: x,x,l
The idea is to find count of occurences of x,y,z from col1 in col2, which in above case is 2,0,0
You could try this:
tab:([]col1:`x`y`z;col2:`x`x`w)
q)exec([]distinct col1)!0^([]count each group col2)distinct col1 from tab
col1| col2
----| ----
x | 2
y | 0
z | 0
Desired value can be found as a map of Col2 occurrences. Which is later looked up by values from Col1
t: ([] Col1:`x`y`z; Col2:`x`x`l);
update Col1Col2Count: 0^(count each group Col2) Col1 from t

Postgres "reverse count(*)" (unnest?)

I'm trying to do what I would call a "reverse count(*)" in PostgreSQL (8.4 +). I want my output to have the exact same number of rows as the number specified in the total column for each letter...
Table 1:
letter | total
-------------
a | 3
b | 2
c | 4
d | 1
Expected table output:
letter
-----
a
a
a
b
b
c
c
c
c
d
I am unsure if and how I could use the unnest function here....
Yes - unnest is what you'll want (once you've got an array of course)
richardh=> SELECT array_fill(letter, ARRAY[total]) FROM expand;
array_fill
------------
{a,a,a}
{b,b}
{c,c,c,c}
{d}
(4 rows)
richardh=> SELECT unnest(array_fill(letter, ARRAY[total])) FROM expand;
unnest
--------
a
a
a
b
b
c
c
c
c
d
(10 rows)
Here's solution that uses a tally or numbers table instead of UNNEST. It's a fairly cross platform solution in that every database has a solution for creating a numbers table although most not as nice as postgresql.
SELECT Letter
FROM
table1
INNER JOIN generate_series(1,100) num
ON table1.total >= num
ORDER BY Letter
SQL Fiddle Demo
I hardcoded the generate_series to 100. However as Clodoado demonstrates you can use MAX(Total) in the call to Generate_series
SELECT Letter
FROM
table1
INNER JOIN
generate_series(
1,
(select max(total) from table1)
) num ON table1.total >= num
ORDER BY Letter
SQL Fiddle Demo

Generate Dynamic Update Statement via TSQL

I have a table with a number of columns:
col1
col2
col3
coln....
I need to generate dynamic UPDATE statement like below which will be used in production for bulk update:
UPDATE TableA
SET TableA.ColA = ValueOfCol2
WHERE
TableA.ColB='A'
Could anyone please share a TSQL script that generate n number of UPDATE statement as above, please?
Thank you
Unless I'm misunderstanding your problem, your example code works:
UPDATE [updateDemo] SET [updateDemo].[col2] = [updateDemo].[col3] WHERE [col4] = 'A'
This is based on the assumption that your table is something like this:
col1 | col2 | col3 | col4
1 P Z A
2 Y Z A
3 K S V
This above update query would result in (changes in square brackets):
col1 | col2 | col3 | col4
1 [Z] Z A
2 [Z] Z A
3 K S V