#mysql #sql #join
#mysql #sql #Присоединиться
Вопрос:
У меня есть 3 таблицы Client, Property и Owner, ниже приведены их схемы,
create table Property (property_no varchar(20), p_address varchar(50), rent_start date, rent_finish
date, rent_per_day int, primary key(property_no,rent_start, rent_finish));
create table Client (client_no varchar(10), client_name char(10), property_no varchar(10), foreign
key(property_no) references Property(property_no),primary key(client_no,client_name,property_no));
create table Owner (owner_no varchar(10), owner_name char(10), property_no varchar(10), foreign
key(property_no) references Property(property_no), primary key(owner_no,property_no));
insert into Property values('pg4', '6 Lawrence St.', '2000-01-07','2001-8-31', 50);
insert into Property values('pg16', '5 Novar Dr.', '2001-09-01','2002-9-1', 70);
insert into Property values('pg4', '6 Lawrence St.', '1999-09-02','2000-6-10', 50);
insert into Property values('pg36', '2 Manor Rd', '2000-10-10','2001-12-1', 60);
insert into Property values('pg16', '5 Novar Dr.', '2002-11-1','2003-8-10', 70);
insert into owner values('co40', 'tina', 'pg4');
insert into owner values('co93', 'tony', 'pg16');
insert into owner values('co93', 'tony', 'pg36');
insert into Client values('cr56','aline', 'pg4');
insert into Client values('cr56','aline', 'pg36');
insert into Client values('cr56','aline', 'pg16');
insert into Client values('cr76','john', 'pg4');
insert into Client values('cr76','john', 'pg16');
Я пытаюсь распечатать вывод, как показано ниже.
Я попробовал запрос ниже, который дает мне странный результат:
Select c.client_No
, p.property_No
, c.client_Name
, p.p_address
, p.rent_start
, p.rent_finish
, DATEDIFF(p.rent_finish, p.rent_start) as Total_Days
, p.Rent_Per_Day
, DATEDIFF(p.rent_finish, p.rent_start)*p.Rent_Per_Day as Total_Rent
, o.owner_No
, o.owner_name
from Property p
right
join Client c
on p.property_no = c.property_no
left
join Owner o
on p.property_no = o.property_no
group
by property_no
, rent_start
order
by client_no desc
, property_no desc;
Вывод :
Любая помощь приветствуется. Заранее спасибо.
Ответ №1:
Ваша таблица не была должным образом нормализована. В таблицах «Клиент» и «Свойство» в качестве вашего property_no также зависит от начала и окончания аренды.
Ответ №2:
Основная проблема заключается не в запросе, а в таблицах:
- Таблицы недопустимы, и операторы create должны быть отклонены СУБД.
- Таблица, которую вы называете Property, на самом деле является таблицей аренды, потому что ее первичным ключом является не номер свойства, а номер свойства плюс время аренды. Вам следует подумать о переименовании таблицы, чтобы люди, читающие запросы, знали, с чем они имеют дело.
- Клиент таблицы пытается ссылаться на таблицу свойств, но делает это только по номеру свойства. Номер свойства не является уникальным в таблице свойств. Следовательно, эта ссылка (внешний ключ) не должна быть разрешена.
- Первичный ключ клиентской таблицы, похоже, не имеет смысла. Почему в ключе указаны и номер клиента, и имя клиента? Это означает, что оба могут иметь дубликаты (например, один и тот же номер, используемый для нескольких клиентов, если у них разные имена). И почему в ключе указан номер свойства? Имеет ли каждое свойство свои собственные номера клиентов? Клиент может даже иметь свойство несколько раз, если они всегда используют другое имя.
- То же самое для владельца таблицы. Вы ссылаетесь на таблицу свойств только по части ее ключа, что должно быть запрещено. Тогда, похоже, это не таблица владельцев, а скорее таблица владельцев, потому что вы храните не только владельца (номер и имя), но и свойство. А поскольку первичным ключом является номер владельца плюс номер свойства, это позволяет нескольким владельцам совместно использовать одно и то же свойство и позволяет владельцам использовать разные имена владельцев для каждого из своих свойств. Это выглядит совершенно неправильно.
Что касается запроса:
- Пожалуйста, никогда не смешивайте соединения справа и слева. Это делает запросы почти нечитаемыми. Используйте только внешние соединения слева (и только если вы действительно хотите внешнего соединения, конечно).
- Соединения приводят к декартовым произведениям, потому что, хотя вы думаете, что имеете дело с таблицей свойств, на самом деле вы имеете дело с таблицей аренды, как описано выше.
- Запрос недействителен, потому что вы группируете только по номеру свойства и началу аренды, но получаете доступ к столбцам, не связанным с группой. Например, таблице свойств / аренды разрешено содержать много строк для такой комбинации, все с разным концом аренды (что, конечно, является еще одной ошибкой в инструкции create table). У вас также может быть несколько клиентов в аренду. И т.д. Никогда не используйте
GROUP BY
, чтобы исправить что-то, чего вы не понимаете в своем запросе. Используйте его только при агрегировании (т. Е. При Наличии агрегированных функций, таких какMIN
,MAX
anndCOUNT
).
В целом: многое нужно исправить. Начните с таблиц. Прочитайте нормализацию. Свойство должно быть идентифицировано по номеру свойства, владелец — по номеру владельца, клиенты — по номерам клиентов. («Идентифицировано» означает первичный ключ.) Тогда вам понадобится отдельная таблица для аренды.
Комментарии:
1. Каковы будут структуры таблиц и ограничения здесь тогда. Можете ли вы привести один пример, чтобы я мог исправить его со ссылкой на это. Заранее спасибо за помощь.
2. Как уже упоминалось: свойство должно быть идентифицировано только по его номеру свойства. У него есть адрес и, вероятно, владелец. У него нет даты. Вы хотите попробовать это, и я скажу вам, правильно ли вы поняли?