title: Kusto !has_any | where value does not contain any value in set
body: <p>Is there a built-in way in Kusto to check that a value does not contain multiple items? I know that I can use has_any to check if an item contains any values in a set, but I can't seem to get it to work with an &quot;!&quot; operator.
  Example:</p>
  <pre><code>let Employees = datatable(Id:int, Name:string, Position:string ) 
  [
     1, &quot;Bob&quot;, &quot;General Manager&quot;,
     2, &quot;Mary&quot;, &quot;Coordinator&quot;,
     3, &quot;John&quot;, &quot;Sales Representitive&quot;
  ];
  Employees
  | where Position !has_any(&quot;Manager&quot;, &quot;Sales&quot;)
  </code></pre>
  <p>Expected output:</p>
  <p><a href="https://i.stack.imgur.com/MHQqx.png" rel="noreferrer"><img src="https://i.stack.imgur.com/MHQqx.png" alt="Expected output" /></a></p>
  <p>If I remove the not operator (!) it works, and returns info for Bob and John. But I want to reverse it from has any/contains any to does <strong>not</strong> contain any. I have also tried</p>
  <pre><code>| where Position has_any !(&quot;Manager&quot;, &quot;Sales&quot;)
  </code></pre>
  <p>But it seems like any combination of has_any and &quot;!&quot; throws a syntax error and won't run. Is there a way to do this without listing out individual !contains statements? i.e. this is not what I am looking for:</p>
  <pre><code>| where Position !contains &quot;Manager&quot; and Position !contains &quot;Sales&quot;
  </code></pre>
  <p>This isn't a big deal for just two conditions but when you're dealing with a long list it would be much better to use has_any with a simple exclamation mark in front of it.</p>
  <br>
  -- UPDATE --
  <p>I only recently found out that <code>has_any</code> actually does not pick up if a field contains any item in a set. To be technically correct, it only picks up if the field <em>has any whole word matches</em> from the set. To clarify, here is an example:</p>
  <pre><code>let TestTable = datatable(Id:int, FirstName:string, LastName:string ) 
  [
     1, &quot;John&quot;, &quot;De La Cruz&quot;,
     2, &quot;Susana&quot;, &quot;Vanderbelt&quot;,
     3, &quot;Stan&quot;, &quot;Manlyman&quot;,
     4, &quot;Henry&quot;, &quot;Van De Camps&quot;,
     5, &quot;Alissa&quot;, &quot;New man&quot;
  ];
  TestTable
  | where not(LastName has_any(&quot;de&quot;, &quot;man&quot;))
  </code></pre>
  <p>Take careful note of the results:</p>
  <p><a href="https://i.stack.imgur.com/MooSe.png" rel="noreferrer"><img src="https://i.stack.imgur.com/MooSe.png" alt="Table results" /></a></p>
  <p>If you where to replace the last line with this</p>
  <pre><code>| where LastName !contains(&quot;de&quot;) and LastName !contains(&quot;man&quot;)
  </code></pre>
  <p>It would yield nothing in the results set. So if you're really going for &quot;where field doesn't <em>contain</em> any value in the set&quot; then as far as I know you have to write out each one individually, there is no such keyword where you can pass in a set for that functionality. If anyone knows of such a keyword please let me know in the comments or a new answer and I will update this question.</p>