Я бы создал еще одну таблицу, примерно с такой структурой
id - AUTOINCREMENT
type - ENUM('1', '2') // тип мойки - обычная, комплексная
time - string // время начала процедуры, например, 10:30
date - string // дата процедуры, например, 26.01.2018
busy - ENUM('1', '0') // занято ли время уже или нет
client_id - int // айди для связи с первой таблицей, чтобы было понятно кто занял время, если оно занято
При создании первой записи на определенную дату (когда на эту дату еще нет записей) создаем сразу все получасовые промежутки, и по мере занятости отмечаем их занятыми. Если на выбранную дату не созданы временные промежутки, значит все свободно.
И таким образом на каждый день выбираем все промежутки, сразу видим, какие заняты, какие нет, какой тип мойки занял (чтобы занимать на час вперед, если комплексная либо показывать, что комплексная недоступна, если свободное окно всего одно).
А первую таблицу оставить просто списком клиентов, без даты и времени. При необходимости, можно посмотреть, когда кто мыл машину.
Это так, навскидку, наверняка в процессе еще какая-то оптимизация придет в голову.