Отчет посещаемости за месяц определенной секции/занятия в клубе (SQL отчет, связи в Postgres SQL)

Хотелось бы попросить помощи. Создаю ПО для небольшого спортивного клуба (возможна сеть) и столкнулся со сложностями. А именно - не могу вывести отчет посещений клуба, точнее, корректно построить SQL запрос. Изначально планировал, чтобы определялось на какую секцию пришел клиент.Тогда, я выделял одну карту для одной секции и карта была рассчитан для для одного клуба, но это неверно, так как одна карта может быть рассчитана на несколько спортивных секций, а так же клубов. Соответственно, М-М разделены на М-1-М. Поэтому исправил создал таблицы, поправил связи. По итогу,то дубликаты лезут в отчет, то еще ужас какой либо...

Запрос до создания связей М-М:

SELECT 
 CONCAT
  (clients.surname, ' ', clients.firstname, ' ', clients.middlename) as FIO, 
  (CASE WHEN history.enter_date = '01-11-2022'  THEN '*' ELSE '' END ) as day1,
  (CASE WHEN history.enter_date = '02-11-2022'  THEN '*' ELSE '' END ) as day2,
  (CASE WHEN history.enter_date = '03-11-2022'  THEN '*' ELSE '' END ) as day3,
  (CASE WHEN history.enter_date = '04-11-2022'  THEN '*' ELSE '' END ) as day4,
  (CASE WHEN history.enter_date = '05-11-2022'  THEN '*' ELSE '' END ) as day5,
  (CASE WHEN history.enter_date = '06-11-2022'  THEN '*' ELSE '' END ) as day6,
  (CASE WHEN history.enter_date = '07-11-2022'  THEN '*' ELSE '' END ) as day7,
  (CASE WHEN history.enter_date = '08-11-2022'  THEN '*' ELSE '' END ) as day8,
  (CASE WHEN history.enter_date = '09-11-2022'  THEN '*' ELSE '' END ) as day9,
  (CASE WHEN history.enter_date = '10-11-2022'  THEN '*' ELSE '' END ) as day10,
  (CASE WHEN history.enter_date = '11-11-2022'  THEN '*' ELSE '' END ) as day11,
  (CASE WHEN history.enter_date = '12-11-2022'  THEN '*' ELSE '' END ) as day12, 
  (CASE WHEN history.enter_date = '13-11-2022'  THEN '*' ELSE '' END ) as day13,
  (CASE WHEN history.enter_date = '14-11-2022'  THEN '*' ELSE '' END ) as day14,
  (CASE WHEN history.enter_date = '15-11-2022'  THEN '*' ELSE '' END ) as day15,
  (CASE WHEN history.enter_date = '16-11-2022'  THEN '*' ELSE '' END ) as day16,
  (CASE WHEN history.enter_date = '17-11-2022'  THEN '*' ELSE '' END ) as day17,
  (CASE WHEN history.enter_date = '18-11-2022'  THEN '*' ELSE '' END ) as day18,
  (CASE WHEN history.enter_date = '19-11-2022'  THEN '*' ELSE '' END ) as day19,
  (CASE WHEN history.enter_date = '20-11-2022'  THEN '*' ELSE '' END ) as day20,
  (CASE WHEN history.enter_date = '21-11-2022'  THEN '*' ELSE '' END ) as day21,
  (CASE WHEN history.enter_date = '22-11-2022'  THEN '*' ELSE '' END ) as day22,
  (CASE WHEN history.enter_date = '23-11-2022'  THEN '*' ELSE '' END ) as day23,
  (CASE WHEN history.enter_date = '24-11-2022'  THEN '*' ELSE '' END ) as day24,
  (CASE WHEN history.enter_date = '25-11-2022'  THEN '*' ELSE '' END ) as day25,
  (CASE WHEN history.enter_date = '26-11-2022'  THEN '*' ELSE '' END ) as day26,
  (CASE WHEN history.enter_date = '27-11-2022'  THEN '*' ELSE '' END ) as day27,
  (CASE WHEN history.enter_date = '28-11-2022'  THEN '*' ELSE '' END ) as day28,
  (CASE WHEN history.enter_date = '29-11-2022'  THEN '*' ELSE '' END ) as day29,
  (CASE WHEN history.enter_date = '30-11-2022'  THEN '*' ELSE '' END ) as day30,
  (CASE WHEN history.enter_date = '30-11-2022'  THEN '*' ELSE '' END ) as day30
FROM 
  clients
INNER JOIN 
  cards ON clients.id = cards.client
INNER JOIN 
  history ON history.card = cards.id
INNER JOIN 
  sections ON sections.id = cards.section
WHERE cards.section = 1

Синий - первичное+уникальное поле, зеленый - внешний ключ, голубой - уникальное поле. Реляционная схема со связями М-М

Со старыми связи отрабатывал хорошо. В данный момент DISTINCT в FIO не исправляет ситуацию. Остаются дубликаты записей клиента после изменений к М-М. И надо ли в таблицу history добавлять club?

Прошу вашей помощи с условиями...

P.S: VS 2022 (C# .NET) БД: Postgres PRO SQL.


Ответы (1 шт):

Автор решения: maximum_makarov

Решил оставить предыдущий вариант (с дополнительнйо привязкой секций к клубам), так как второй нарушает логику (тот, что в заголовке). введите сюда описание изображения

И прикреплю сразу код SQL, для того, чтобы был и не потерялся. В данном случаю, все же оставляю привязку одной карты к одной секции.

    SELECT 
    CONCAT
        (clients.surname, ' ', 
        clients.firstname, ' ', 
        clients.middlename) as FIO, 
        cards.id,
        (CASE WHEN to_char(history.enter, 'dd-mm-yyyy') = '01-12-2022'  THEN '*' ELSE ''
        END ) as day1,
        (CASE WHEN to_char(history.enter, 'dd-mm-yyyy') = '02-12-2022'  THEN '*' ELSE ''
        END ) as day2, 
... Еще дни ...
FROM history 
INNER JOIN 
    cards ON cards.client = history.id 
INNER JOIN 
    clients ON clients.id = cards.client 
INNER JOIN 
    sections ON sections.id = cards.section 
WHERE sections.id = 1

KordDEM, благодарю за помощь!

→ Ссылка