попытка напечатать вывод ниже по запросу

#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 annd COUNT ).

В целом: многое нужно исправить. Начните с таблиц. Прочитайте нормализацию. Свойство должно быть идентифицировано по номеру свойства, владелец — по номеру владельца, клиенты — по номерам клиентов. («Идентифицировано» означает первичный ключ.) Тогда вам понадобится отдельная таблица для аренды.

Комментарии:

1. Каковы будут структуры таблиц и ограничения здесь тогда. Можете ли вы привести один пример, чтобы я мог исправить его со ссылкой на это. Заранее спасибо за помощь.

2. Как уже упоминалось: свойство должно быть идентифицировано только по его номеру свойства. У него есть адрес и, вероятно, владелец. У него нет даты. Вы хотите попробовать это, и я скажу вам, правильно ли вы поняли?