kdb/Q:如何选择至少有一列不为空的行?

kdb/Q: How to select rows where at least one column is not null?

提问人:mmv456 提问时间:9/22/2023 更新时间:9/27/2023 访问量:68

问:

我有一个表格,如下所示:

编号 名字 1_Day_Time 2_Day_Time
2乙 五月 762
8D(8D) 空气 142
W2系列 提姆 908 332
9小时 蜜蜂
5E的 712

如何在 kdb/Q 中仅选择1_Day_Time列中至少有一个非 null 且2_Day_Time列的行?

我的预期输出如下,删除了 ID 9H 行,因为 1_Day_Time 和 2_Day_Time 列中都有空值:

编号 名字 1_Day_Time 2_Day_Time
2乙 五月 762
8D(8D) 空气 142
W2系列 提姆 908 332
5E的 712
kdb

评论


答:

1赞 scottstein37 9/22/2023 #1

我建议您不要使用以数字开头的列名(例如,更喜欢“One_Day_Time”而不是“1_Day_Time”),否则您将需要功能选择。但这里有一些可能的解决方案:

q)show t: ([] ID:`2B`8D`W2`9H`5E; Name:`May`Air`Tim`Bee`Ice; One_Day_Time: 762 0N 908 0N 712; Two_Day_Time: 0N 143 332 0N 0N)
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               143
W2 Tim  908          332
9H Bee
5E Ice  712

q)select from t where not null[One_Day_Time] & null[Two_Day_Time]
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               143
W2 Tim  908          332
5E Ice  712

q)select from t where (not null One_Day_Time) | (not null Two_Day_Time)
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               143
W2 Tim  908          332
5E Ice  712

q)select from t where {not all null x} each (One_Day_Time,'Two_Day_Time)
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               143
W2 Tim  908          332
5E Ice  712

评论

0赞 mmv456 9/22/2023
非常感谢!只是好奇,为什么列名不能以数字开头?
0赞 scottstein37 9/22/2023
根据 code.kx.com/q/basics/syntax,“名称中的第一个字符不能是数字或下划线”
0赞 scottstein37 9/22/2023
但是请注意,您可以使用 xcol 重命名列,使其以数字开头,但如果您希望从该表中进行选择,则需要使用功能选择:********************Col2:3 4 5;歌罗西书 3:6 7, 8);t: xcol[$(“1_Day_Time”;“2_Day_Time”))!('$(“1_Day_Time”;“2_Day_Time”))]$("1_Day_Time"; "2_Day_Time"; "Col3"); t]; show ?[t; (); 0b; (
2赞 Thomas Smyth - Treliant 9/22/2023 #2

如果要检查许多列(而不是 2 列),则可以将此示例与列列表一起使用。优点是很容易添加更多列以供考虑:

q)tab:([]ID:`2B`8D`W2`9H`5E;Name:`May`Air`Tim`Bee`Ice;One_Day_Time:762 0N 908 0N 712;Two_Day_Time:0N 142 332 0N 0N)
q)cls:`One_Day_Time`Two_Day_Time
q)?[tab;enlist(not;(all;enlist,{(null;x)}'[cls]));0b;()]
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               142
W2 Tim  908          332
5E Ice  712

如果这些列名称可能有所不同,它也很有用。

0赞 cillianreilly 9/27/2023 #3

另一种避免qsql或函数选择的解决方案。似乎至少和qsql或函数选择答案一样快:

q)t:([]ID:`2B`8D`W2`9H`5E;Name:`May`Air`Tim`Bee`Ice;One_Day_Time:762 0N 908 0N 712;Two_Day_Time:0N 142 332 0N 0N)
q)c:`One_Day_Time`Two_Day_Time
q)t where not all null t c
ID Name One_Day_Time Two_Day_Time
---------------------------------
2B May  762
8D Air               142
W2 Tim  908          332
5E Ice  712

也易于扩展到其他列。