Как создать 2 таблицы с внешним и первичным ключом в скрипте sql? - PullRequest
0 голосов
/ 06 февраля 2020

2 таблиц RetailOutlet и SalesMan, обе связаны ROID, ROID является первичным, уникальным для Retail Outlet.

Продавец имеет SID первичного ключа, но также имеет ROID внешнего ключа.

http://sqlfiddle.com/#! 9 / b1cd8a

CREATE TABLE IF NOT EXISTS `RetailOutlet` (
  `id` int(6) unsigned NOT NULL,
  `year` int(4) unsigned NOT NULL,
  `location` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `RetailOutlet` (`id`, `year`, `location`) VALUES
  ('1', '1994', 'oregon'),
  ('2', '1990', 'amazon'),
  ('3', '2004', 'california'),
  ('4', '1997', 'newyork');

CREATE TABLE IF NOT EXISTS `SalesMan` (
  `sid` int(6) unsigned NOT NULL,  
  `sname` varchar(200) NOT NULL,
  `manager` int(4) unsigned NOT NULL,
  `id` int(6) unsigned NOT NULL,
  PRIMARY KEY (`sid`),
  FOREIGN KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `SalesMan` (`sid`, `sname`, `manager`, `id`) VALUES
  ('1', 'john', 'fingao', '2'),
  ('2', 'bekc', 'dilda', '3'),
  ('3', 'aaa', 'elda', '4'),
  ('4', 'erjan', 'rrrrokcks', '1');

Мой запрос был на получение магазинов не в Нью-Йорке, где есть только 1 продавец, в алфавитном порядке по названию.

    SELECT * FROM SalesMan s INNER JOIN RetailOutlet r ON 
s.ROID = r.ROID where count(s.SID) = 1 and 
r.Location NOT LIKE 'New York' order by s.sname desc

Я не могу понять, что не работает.

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Для правильного тестирования я добавил несколько продавцов:

INSERT INTO `SalesMan` (`sid`, `sname`, `manager`, `id`) VALUES
  ('1', 'john', 'fingao', '2'),
  ('2', 'bekc', 'dilda', '3'),
  ('3', 'aaa', 'elda', '4'),
  ('4', 'erjan', 'rrrrokcks', '1'),
  ('5', 'john', 'fingao', '1'),
  ('6', 'benny', 'fingao', '1'),
  ('7', 'silvia', 'fingao', '1'),
  ('8', 'peter', 'dilda', '2'),
  ('9', 'karen', 'dilda', '2');

Так как вас интересуют записи в RetailOutlet, я изменил порядок объединения, так что запись в форме RetailOutlet основа вашего поиска. Затем я делаю обычные JOIN и GROUP BY SalesMan, исключая записи, которые не имеют ровно одну запись:

SELECT *
  FROM RetailOutlet r
 INNER JOIN SalesMan s ON s.id = r.id
 WHERE r.Location NOT LIKE 'newyork'
 GROUP BY s.id
HAVING count(s.id) = 1
 ORDER by s.sname DESC

. Этот dbfiddle показывает рабочие шаги от создания таблиц до последний запрос.


Предупреждение: Нормальной практикой является использование идентификатора для чего-либо, кроме текущего идентификатора таблицы. Использование id для столбца, который ссылается на другую таблицу, в то время как sid именуется локальными таблицами фактический id, скорее всего, запутает других разработчиков. Я предлагаю вам изменить на:

CREATE TABLE IF NOT EXISTS `SalesMan` (
  `id` int(6) unsigned NOT NULL,  
  `sname` varchar(200) NOT NULL,
  `manager` int(4) unsigned NOT NULL,
  `rid` int(6) unsigned NOT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`rid`) REFERENCES RetailOutlet (`id`)
) DEFAULT CHARSET=utf8;

.. и соответственно изменить ваши вставки и запросы.

0 голосов
/ 06 февраля 2020

В объявлении внешнего ключа есть ошибка, в нем должно быть указано, на какой первичный ключ он ссылается:

FOREIGN KEY (`id`) REFERENCES RetailOutlet (`id`)

Это полное значение SQL Я использую:

CREATE TABLE IF NOT EXISTS `RetailOutlet` (
  `id` int(6) unsigned NOT NULL,
  `year` int(4) unsigned NOT NULL,
  `location` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
);

INSERT INTO `RetailOutlet` (`id`, `year`, `location`) VALUES
  ('1', '1994', 'oregon'),
  ('2', '1990', 'amazon'),
  ('3', '2004', 'california'),
  ('4', '1997', 'newyork');


CREATE TABLE IF NOT EXISTS `SalesMan` (
  `sid` int(6) unsigned NOT NULL,  
  `sname` varchar(200) NOT NULL,
  `manager` VARCHAR(200) NOT NULL,
  `id` int(6) unsigned NOT NULL,
  PRIMARY KEY (`sid`),
  FOREIGN KEY (`id`) REFERENCES RetailOutlet (`id`)
);

INSERT INTO `SalesMan` (`sid`, `sname`, `manager`, `id`) VALUES
  ('1', 'john', 'fingao', '2'),
  ('2', 'bekc', 'dilda', '3'),
  ('3', 'aaa', 'elda', '4'),
  ('4', 'erjan', 'rrrrokcks', '1');

РЕДАКТИРОВАТЬ:

И ваш запрос выбора также не будет работать с этой COUNT функцией в предложении where.

 SELECT * 
 FROM SalesMan s 
 INNER JOIN RetailOutlet r ON s.id = r.id
 WHERE r.Location NOT LIKE 'New York' 
 ORDER BY s.sname desc

EDIT 2:

Поскольку в ОП есть опечатка:

 SELECT * 
 FROM SalesMan s 
 INNER JOIN RetailOutlet r ON s.id = r.id
 WHERE r.Location NOT LIKE 'newyork' 
 ORDER BY s.sname desc
...