You don't say if #readstatus can have values other than 'Read' or 'Unread'. I assume it can't. The templates below won't work if my assumption is wrong.
These two templates return 'Yes' if #readstatus has more than one value for a series, the empty string otherwise. The GPM template is probably easier for you to maintain. The Python template is much faster.
Edit: add comments to the template, and remove the trailing comma
Code:
program:
globals(answers = '');
if !answers then
# Get a list of series names
series_names = book_values('series', 'id:true', ',', 1);
# Loop over the series names
for series in series_names:
# Get all the values in the '#readstatus column
values = book_values('#readstatus', 'series:="' & series & '"', ',', 1);
if list_count(values, ',') > 1 then
# More than one value found. Store the series in the answers global for later use
answers = answers & series & ','
fi
rof;
# remove the trailing comma
answers = re(answers, ',$', '');
set_globals(answers)
fi;
str_in_list(answers, ',', $series, 'Yes', '')
Edit: Fix bug where identical values were counted as unique
Code:
python:
def evaluate(book, context):
db = context.db.new_api
answer = context.globals.get('answer', None)
if answer is None:
answer = set()
all_series = db.all_field_names('series')
for series in all_series:
series_id = db.get_item_id('series', series)
books_in_series = db.books_for_field('series', series_id)
vals = db.all_field_for('#readstatus', books_in_series)
unique_vals = {v for v in vals.values()}
if len(unique_vals) > 1:
answer.add(series)
context.globals['answer'] = answer
return 'Yes' if book.series in answer else ''
The 'globals' stuff is there so the template computes the answer data once for the search instead of for every book.