【问题标题】:how to create 2 tables with foreign and primary key in sql fiddle?如何在 sql fiddle 中创建 2 个具有外键和主键的表?
【发布时间】:2020-02-06 12:07:18
【问题描述】:

2 个表分别是 RetailOutlet 和 SalesMan,两者都通过 ROID 连接,ROID 是主要的,对于 Retail Outlet 是唯一的。

Salesman 有主键 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

我不知道什么不起作用。

【问题讨论】:

    标签: sql inner-join sqlfiddle


    【解决方案1】:

    为了正确测试,我添加了一些推销员:

    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 用于 current 表 id 以外的任何东西都是不正常的做法。将 id 用于引用另一个表的列,同时将 sid 命名为本地表 actual 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;
    

    ..并相应地更改您的插入和查询。

    【讨论】:

    • 兄弟非常详细的回答谢谢你..我确实怀疑“有”在groupby之后,它是必需的......
    • 没错。虽然它可以在没有 GROUP BY 的情况下使用,但不是在这种情况下。如果您更感兴趣,请参阅What's the difference between HAVING and WHERE?
    【解决方案2】:

    你的外键声明有错误,它应该说明它引用的是哪个主键:

    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');
    

    编辑:

    而且您的选择查询也不适用于 where 子句中的 COUNT 函数。

     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
    

    编辑 2:

    因为 OP 中有错字:

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

    【讨论】:

    • 由于WHERE r.Location NOT LIKE 'New York'中的拼写错误,这将不起作用
    • 它是从 OP 复制的。它会运行,这只是一个无关紧要的检查;)
    • 链接中的小提琴不包含任何选择。我想我不知道什么是行不通的涵盖了几个问题:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多