2017-10-19 4 views
2

Je cherche un moyen d'écrire fonction sélection dans KDB de telle sorte que les phrases where ne s'appliquent que si la colonne existe (afin d'éviter les erreurs). Si la colonne n'existe pas, elle est définie par défaut sur true.KDB Appliquer où phrase seulement si la colonne existe

J'ai essayé, mais ça n'a pas

enlist(|;enlist(in;`colname;key flip table);enlist(in;`colname;filteredValues[`colname])); 

J'ai essayé d'écrire une simple expression booléenne et utiliser Parse pour obtenir ma forme fonctionnelle

(table[`colname] in values)|(not `colname in key flip table) 

Mais KDB n'a pas de court circuit donc l'expression de gauche est encore évaluée malgré l'expression de droite évaluant à vrai. Cela a provoqué une sortie étrange boolean$() qui est une liste de booléens tous évaluant à faux 0b

Toute aide est appréciée. Merci!

EDIT 1: Je dois rejoindre une série de conditions avec le paramètre spécifié dans le dictionnaire filters

cond,:(,/) {[l;k] enlist(in;k;enlist l[k])}[filters]'[a:(key filters)] 

Puis je passe cette cond sur et il est exécuté sur quelques différentes sélections sur différentes tables. Comment puis-je m'assurer que toute expression conditionnelle que je mets à la place de enlist(in;k;enlist l[k] ne sera évaluée que lorsque l'instruction select sera exécutée.

Répondre

1

Vous pouvez utiliser le if-else conditionnel ici $ pour faire ce que vous voulez

Par exemple:

q)$[`bid in cols`quotes;enlist (>;`bid;35);()] 
> `bid 35 
q)$[`bad in cols`quotes;enlist (>;`bad;35);()] 

Notez que dans le second exemple, le retour est une liste vide, comme cette colonne est pas dans la table des citations

vous pouvez mettre cela dans la fonction sélectionner comme ceci:

?[`quotes;$[`bid in cols`quotes;enlist (>;`bid;35);()];0b;()] 

et la clause where sera appliquée la colonne est présente, sinon aucune clause where sera appliquée:

q)count ?[`quotes;$[`bid in cols`quotes;enlist (>;`bid;35);()];0b;()] 
541 //where clause applied, table filtered 
q)count ?[`quotes;$[`bad in cols`quotes;enlist (>;`bad;35);()];0b;()] 
1000 //where clause not applied, full table returned 

Hope this helps

Jonathon

AquaQ Analytics


EDIT: Si je comprends correctement votre question mise à jour, vous pourriez être en mesure de faire quelque chose comme suit. Tout d'abord, nous allons définir un exemple « filtres » dictionnaire:

q)filters:`a`b`c!(1 2 3;"abc";`d`e`f) 
q)filters 
a| 1 2 3 
b| a b c 
c| d e f 

Voici donc nous supposons que quelques colonnes différentes de types différents, à des fins d'illustration.Vous pouvez construire votre liste de clauses where comme ceci:

q)(in),'flip (key filters;value filters) 
in `a 1 2 3 
in `b "abc" 
in `c `d`e`f 

(ce qui est équivalent au code que vous deviez générer cond, mais il est un peu plus propre & plus efficace - vous aussi avez des valeurs fait appel, ce qui isn 't nécessaire)

Vous pouvez ensuite utiliser un vector conditional pour générer votre liste des clauses where à appliquer à une table donnée, par ex.

q)t:([] a:1 2 3 4 5 6;b:"adcghf") 
q)?[key[filters] in cols[t];(in),'flip (key filters;value filters);count[filters]#()] 
(in;`a;,1 2 3) 
(in;`b;,"abc") 
() 

Comme vous pouvez le voir, dans cet exemple la table "t" a des colonnes a et b, mais pas c. Donc, en utilisant le vecteur conditionnel, vous obtenez les clauses where pour a et b mais pas c.

Enfin pour appliquer effectivement cette liste de sortie où les clauses de la table, vous pouvez utiliser un over pour appliquer chacun à son tour:

q)l:?[key[filters] in cols[t];(in),'flip (key filters;value filters);count[filters]#()] 
q){?[x;$[y~();y;enlist y];0b;()]}/[t;l] 
a b 
--- 
1 a 
3 c 

Une chose à noter ici est que, dans la clause where de la sélection fonctionnelle nous devons vérifier si y est une liste vide - il en est ainsi, nous pouvons enrôlons si ce n'est pas une liste vide

Hope this helps

+0

Merci beaucoup, votre code ne fonctionne pas pour moi. Cependant, il y a une autre partie à mon problème. S'il vous plaît jeter un oeil à mon édition et conseiller. Merci encore – KeenSeeker99

+1

Toutes mes excuses pour le retard, mais ont ajouté une réponse étendue pour répondre à la deuxième partie de votre question, espérons que cela aide! –