you should save the output of your alert in a lookup or a Summary index and the exclude the content of it from the results, something like this (sorry if the regex will be not correct but I cannot read your code because you didn't use Code Sample button):
earliest=-60m@m index= fail
| rex field=_raw ": (?P.)"
| serch NOT [ | inputlookup test.csv | fields Error ]
| stats earliest(_time) as Earliest, latest(_time) as Latest, count by Error
| eval Earliest=strftime(Earliest, "%F %T"), Latest=strftime(Latest, "%F %T")
| table Earliest Latest Error count
| outputlookup test.csv
the problem is that in this way everytime you override the lookup, this means that if an error was found at 8.00, it's excluded at 8.15, but it's fired again at 8.30: is this acceptable for you?
Otherwise, you could find a different approach: create two alerts: one executed every 15 minutes that add results to the lookup (last command is | outputlookup test.csv append=1) and every hour you run the alert that overrides lookup.