Как сделать выборку первой и третьей колонки исходя из даты (2 колонка)?

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

Первое условие - отобразить всех людей посетивщих и не посетивщих магазин за определенный период., Второе условие - Отобразить магазины которые были посещены или нет за определенный период.

Я вот не могу свзязать эти данные. Вопрос как связать 1 и 3 колонку. То есть в 3 колонке должны отображатся магазины не посещенные или поещенные, тогда как привязать людей, и наоборот, Если человек не посещал магазин. По условиям запрещено использовать операторы.

NOT IN, IN, NOT EXISTS, EXISTS, UNION, EXCEPT, INTERSECT

Я реализовал таким способом, но вот как сделать выборку не могу понять.

Есть три таблицы, Покупатели связана с таблицей, визит, магазины связано с висит, и визит где есть ID покупателей и ID магазинов.

Покупатели

create table person
( id bigint primary key ,
  name varchar(MAX) not null,
  age integer not null default 10,
  gender varchar(6) default 'female' not null ,
  address varchar(MAX)
  );

alter table person add constraint ch_gender check ( gender in ('female','male') );

insert into person values (1, 'Anna', 16, 'female', 'Moscow');
insert into person values (2, 'Andrey', 21, 'male', 'Moscow');
insert into person values (3, 'Kate', 33, 'female', 'Kazan');
insert into person values (4, 'Denis', 13, 'male', 'Kazan');
insert into person values (5, 'Elvira', 45, 'female', 'Kazan');

Магазины

create table pizzeria
(id bigint primary key ,
 name varchar(50) not null ,
 rating numeric not null default 0);

alter table pizzeria add constraint ch_rating check ( rating between 0 and 5);

insert into pizzeria values (1,'Pizza Hut', 4.6);
insert into pizzeria values (2,'Dominos', 4.3);
insert into pizzeria values (3,'DoDo Pizza', 3.2);
insert into pizzeria values (4,'Papa Johns', 4.9);
insert into pizzeria values (5,'Best Pizza', 2.3);
insert into pizzeria values (6,'DinoPizza', 4.2);

Визиты покупателй

create table person_visits
(id bigint primary key ,
 person_id bigint not null ,
 pizzeria_id bigint not null ,
 visit_date date not null default GETDATE(),
 constraint uk_person_visits unique (person_id, pizzeria_id, visit_date),
 constraint fk_person_visits_person_id foreign key  (person_id) references person(id),
 constraint fk_person_visits_pizzeria_id foreign key  (pizzeria_id) references pizzeria(id)
 );

insert into person_visits values (1, 1, 1, '2022-01-01');
insert into person_visits values (2, 2, 2, '2022-01-01');
insert into person_visits values (3, 2, 1, '2022-01-02');
insert into person_visits values (4, 3, 5, '2022-01-03');
insert into person_visits values (5, 3, 6, '2022-01-04');
insert into person_visits values (6, 4, 5, '2022-01-07');
insert into person_visits values (7, 4, 6, '2022-01-08');
insert into person_visits values (8, 5, 2, '2022-01-08');
insert into person_visits values (9, 5, 6, '2022-01-09');
insert into person_visits values (10, 6, 2, '2022-01-09');
insert into person_visits values (11, 6, 4, '2022-01-01');
insert into person_visits values (12, 7, 1, '2022-01-03');
insert into person_visits values (13, 7, 2, '2022-01-05');

Первый запрос, выбираю сотрудников которые посещали магазин в определенную дату

DECLARE @DataMin DATE = '2022-01-01';
DECLARE @DataMax DATE = '2022-01-03';

CREATE TABLE ##ResultVisitPersons
(namePerson NVARCHAR(100), resultVisit BIT, visitDuringPeriod NVARCHAR(100), pizzeriaName NVARCHAR(100), pizzeriaID INT)

INSERT INTO ##ResultVisitPersons
SELECT
    visit.name,
    visit.resultVisit,
    visit.visitDuringPeriod,
    visit.pizzeriaName,
    visit.pizzeria_id
FROM (
  SELECT 
    person.name,
    CASE 
        WHEN person_visits.visit_date BETWEEN @DataMin AND @DataMax THEN 1
        ELSE 0
    END AS resultVisit,
    CASE 
        WHEN person_visits.visit_date BETWEEN @DataMin AND @DataMax THEN LEFT(CONVERT(VARCHAR, person_visits.visit_date, 104), 10)
        ELSE 'NULL'
    END AS visitDuringPeriod,
    person_visits.pizzeria_id,
    pizzeria.name as pizzeriaName
FROM person_visits
JOIN person ON person.id = person_visits.person_id
JOIN pizzeria ON pizzeria.id = person_visits.pizzeria_id
) visit

Вторым запросом, сделал выборку посещания магазинов за тот же промежуток времени.

CREATE TABLE ##ResultVisitPizzeria
(visitDuringPeriod BIT, result NVARCHAR(100), namePizzeria NVARCHAR(100), id INT)

INSERT INTO ##ResultVisitPizzeria
SELECT 
    CASE 
        WHEN person_visits.visit_date BETWEEN @DataMin AND @DataMax THEN 1
        ELSE 0
    END AS visitDuringPeriod,
        CASE 
        WHEN person_visits.visit_date BETWEEN @DataMin AND @DataMax THEN N'Ресторан посещали'
        ELSE N'Ресторан не посещали'
    END AS isVisitDuringPeriod,
    pizzeria.name,
    pizzeria.id
FROM person_visits
JOIN pizzeria ON pizzeria.id = person_visits.pizzeria_id

введите сюда описание изображения введите сюда описание изображения введите сюда описание изображения


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

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

Не совсем понятен вопрос. Может, просто сделать два отдельных подзапроса по покупателям и магазинам, потом соединить через FULL JOIN ?

SELECT
  p.[name],
  ISNULL(pv.[visit_date], pv2.[visit_date]) AS [visit_date],
  pz.[name]
FROM
  (
    [person] p
    LEFT JOIN [person_visits] pv ON pv.[person_id] = p.[id] AND pv.[visit_date] BETWEEN @DataMin AND @DataMax
  )
  FULL JOIN (
    [pizzeria] pz
    LEFT JOIN [person_visits] pv2 ON pv2.[pizzeria_id] = pz.[id] AND pv2.[visit_date] BETWEEN @DataMin AND @DataMax
  ) ON pv.[id] = pv2.[id]
name visit_date name
Anna 2022-01-01 Pizza Hut
Andrey 2022-01-01 Dominos
Andrey 2022-01-02 Pizza Hut
Kate 2022-01-03 Best Pizza
Denis NULL NULL
Elvira NULL NULL
NULL 2022-01-03 Pizza Hut
NULL NULL DoDo Pizza
NULL NULL DinoPizza
NULL 2022-01-01 Papa Johns
→ Ссылка