从单个查询创建多个视图表

Posted

技术标签:

【中文标题】从单个查询创建多个视图表【英文标题】:Create multiple view tables from a single query 【发布时间】:2017-11-26 18:24:31 【问题描述】:

我有一个创建视图表的查询,如下所示:

CREATE OR REPLACE VIEW view_table AS
SELECT ………………
       ………………
FROM shop_table 
     JOIN …………  ON ………… = ………… 
     JOIN …………  ON ………… = ………… 
WHERE shopid = 1 
GROUP BY e.employee_name 
ORDER BY COUNT(p.payment_amount) ASC LIMIT 1

我的数据库中有 20 家商店。如您在WHERE shopid = 1 中所见,上面的查询将创建仅包含单个商店数据的视图表。

现在我想在运行此查询时为我的数据库中的每一家(全部 20 家)商店创建一个视图表,而不仅仅是一个。

我该怎么做?我是否必须每次创建 20 个不同的查询并更改 WHERE 子句中的值,还是有更简单的方法来实现这一点?

【问题讨论】:

我认为您可能会编写一个接受参数的函数,并在函数中使用该参数来实现 WHERE 子句,以便获得您想要的商店。 你用什么加入这个表?为什么不使用 UNION ALL? 这是一个 SQL 反模式。为什么您希望shop_table 中的每个条目都有一个视图?为什么不采用每家商店返回一名员工的视图? (各店表现最佳) @MatBailie 任何想法我可以按照您对我的查询提出的建议。我可以删除WHERE 子句,但这将返回所有员工。我怎样才能从每个商店中获得销售额最多的员工。 【参考方案1】:

mysql 中有多种方法可以做到这一点,但都不是很漂亮。我相信 MySQL 8 将拥有 ROW_NUMBER()RANK() 以使其更加更清洁、更快,但现在我将在视图中执行类似的操作...

https://www.db-fiddle.com/f/xxcCnsJWgbXBxhRx39bUV9/0

create table shop (
  id int
);

create table employee (
  id int,
  shop_id int
);

create table sale (
  employee_id int,
  payment_amount int
);


insert into shop values (1);
insert into shop values (2);
insert into shop values (3);


insert into employee values (1, 1);
insert into employee values (2, 1);
insert into employee values (3, 1);

insert into employee values (4, 2);
insert into employee values (5, 2);
insert into employee values (6, 2);

insert into employee values (7, 3);
insert into employee values (8, 3);
insert into employee values (9, 3);


insert into sale values (1, 100);
insert into sale values (1, 200);

insert into sale values (2, 300);

insert into sale values (3, 50);
insert into sale values (3, 50);
insert into sale values (3, 50);


insert into sale values (4, 200);
insert into sale values (4, 300);

insert into sale values (5, 400);

insert into sale values (6, 150);
insert into sale values (6, 150);
insert into sale values (6, 150);

insert into sale values (7, 200);
insert into sale values (7, 100);

insert into sale values (8, 250);

insert into sale values (9, 100);
insert into sale values (9, 150);
insert into sale values (9, 150);


create view shop_employee_total_sale as
  select
    employee_id, shop_id, sum(payment_amount) total_payment
  from
    sale
  inner join
    employee
      on employee.id = sale.employee_id
  group by
    employee_id, shop_id
;

create view shop_top_employee as
  select
    shop_employee_total_sale.shop_id,
    shop_employee_total_sale.employee_id,
    shop_employee_total_sale.total_payment
  from
    shop_employee_total_sale
  inner join
  (
    select shop_id, max(total_payment) as total_payment from shop_employee_total_sale group by shop_id
  )
    shop_top_total
      on  shop_top_total.shop_id       = shop_employee_total_sale.shop_id
      and shop_top_total.total_payment = shop_employee_total_sale.total_payment
;

select * from shop_top_employee;

select * from shop_top_employee where shop_id = 1;

select * from shop_top_employee where shop_id = 2;

select * from shop_top_employee where shop_id = 3;

请注意,我特意选择了一个示例,其中一家商店有两名员工支付相同的总付款。在这种情况下,他们都是“表现最好的人”,并且为该商店返回了两条记录。

编辑:举例来说,当您访问RANK()...

CREATE VIEW better_shop_top_employee AS
  SELECT
    employee_id,
    shop_id,
    SUM(payment_amount) total_payment,
    RANK() OVER (PARTITION BY shop_id ORDER BY SUM(payment_amount) DESC)  shop_rank
  FROM
    sale
  INNER JOIN
    employee
      ON employee.id = sale.employee_id
  GROUP BY
    employee_id,
    shop_id
;

SELECT * FROM better_shop_top_employee WHERE shop_id = 1 AND rank = 1

【讨论】:

谢谢。我创建了一个新问题,其中包含我的查询和问题。如果可以的话,请你看看它并定制答案。谢谢。 ***.com/questions/47533531/… 你想让我为你做这件事,但你甚至没有对 this 问题的任何一个答案投赞成票? ;)【参考方案2】:

您将需要一个存储过程。这是一个关于在mysql中使用存储过程的教程的链接

http://www.mysqltutorial.org/stored-procedures-parameters.aspx

如果您想在另一个查询中将结果用作表本身,那么函数是可行的方法,但它可以实现的功能更加有限。 (虽然你的例子很简单)

【讨论】:

以上是关于从单个查询创建多个视图表的主要内容,如果未能解决你的问题,请参考以下文章

SQL 如何查询指定架构中所有表(或视图)的名称

3.复杂查询

如何在路由器上注册单个视图(不是视图集)?

laravel5.2如何创建视图表

从视图表中获取数据时出现 Laravel 错误

MySQL 中查询/查看表的大小限制是多少?