Как сделать выборку первой и третьей колонки исходя из даты (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 шт):
Не совсем понятен вопрос. Может, просто сделать два отдельных подзапроса по покупателям и магазинам, потом соединить через 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 |