我有一个由字符列表组成的联接表。
q)t:([] a:`c`d; b:("";"fill"));
q)s:([] a:`b`c`c; b:("";"";""))
q)select from t lj select b by a from s
Output:
a b
---------
c ("";"") / This is the culprit want to replace it with null character
d "fill"
join的输出包含一个空字符列表。 我想用空字符代替它。
Expected output:
a b
---------
c ""
d "fill"
尝试:几次失败的尝试
q)update b:?[null in b;raze b;b]from select from t lj select b by a from s
q)update b:?["" in b;raze b;b]from select from t lj select b by a from s
答案 0 :(得分:2)
要将空字符串列表替换为空字符串,可以尝试以下查询:
q) select from t lj select (b;"")all""~/:b by a from s
输出:
a b
--------
c ""
d "fill"
说明:
基本上,空字符串列表来自右表中的group
命令。因此,在分组阶段,我们可以匹配特定b column values
值的分组列表(a
)中的所有项目是否为空字符串。如果他们只是用一个空字符串替换它们。
q) select (b;"")all""~/:b by a from s
a| b
-| --
b| ""
c| ""
对于a
= c,b
的分组值为(“”;“”)。让我们分解命令:
q) b:("";"")
q) ""~/:b / output 11b
q) all ""~/:b / output 1b
q)(b;"") all ""~/:b / output ""
最后一个命令是列表索引。如果前一条命令的返回值为1b,则表示所有项目均为空字符串,则返回""
,否则返回实际b。
编辑:
根据TerryLynch答案的评论部分中的讨论,您的要求似乎是:
b
列表中的所有值都是空字符串,则返回一个空字符串。b
的值是空字符串和非空字符串的混合,则删除所有空字符串。为此,您可以使用以下查询:
q) select from t lj select b:raze ("";b except enlist "") by a from s
但这将导致b
列中不同值的类型不同。一个空字符串将为10h,所有非空字符串列表将为0h。
对于一致的类型,可以使用下面的查询返回enlist""
而不是""
,但这不是空字符串:
q) select from t lj select b:{(c;enlist "")()~c:x except enlist ""}b by a from s
答案 1 :(得分:1)
另一种解决方案是将raze
的所有结果简单地b
在一起。使用较少的where
子句和较少匹配(~
)的操作。
q)update raze'/[b] from (t lj select b by a from s)
a b
--------
c ""
d "fill"
在这里,我已经习惯于将更多未知水平的入伍情况考虑在内,作为预防措施,然后将其应用于lj
中的每一行。对于您的情况,更快的解决方案是
update raze each b from (t lj select b by a from s)
这将与Rahuls答案给出不同的结果
q)update raze each b from (t lj select b by a from s)
a b
--------
c "str"
d "fill"
q) select from t lj select (b;"")all""~/:b by a from s
a b
------------
c ("";"str")
d "fill"
q)update raze each b from (t lj select b by a from s)
a b
--------
c "str"
d "fill"
答案 2 :(得分:1)
我认为您无需决定解决不良结果,而是需要决定要对c
表中重复的s
行执行什么操作。您正在按a
列分组,但是它具有重复项,因此它应如何表现..应该采用第一个值,还是应该采用最后一个值?是否应该将两个字符串附加在一起?如果您解决了该问题,则可以避免此问题,例如:
q)t lj select last b by a from s
a b
--------
c ""
d "fill"