MySQL高效数据到联结表查询

时间:2018-04-04 07:31:28

标签: mysql sql database junction-table

问题:

我想将表格 companies_1 中的类别链接移到 company_categories 表中。 company_categories 表中的 company_id 需要等于 companies_2 表的 id companies_1 companies_2 表的记录通过“ name ” - 列链接。

  • 下面的当前代码花了我一个晚上,仍未完成!我想学习更有效率并加快这一进步。我觉得有很多优化因为有很多公司记录。
  • 另一个问题是我发现无法在循环时检查查询的位置(导致无法检查进度)。因为进展花了这么长时间我杀了查询,我正在寻找一种更好的方法来解决这个问题。

信息:

有一个公司的表格如下:

----------------------------------------
| companies_1                          |
----------------------------------------
| id   |  category_id   | name         |
----------------------------------------
| 1    |  1             | example-1    |
| 2    |  2             | example-1    |
| 3    |  1             | example-2    |
| 4    |  2             | example-2    |
| 5    |  3             | example-2    |
| 6    |  1             | example-3    |
----------------------------------------

包含DISTINCT公司名称的表格:

-------------------------
| companies_2           |
-------------------------
| id   |   name         |
-------------------------
| 1    |   example-1    |
| 2    |   example-2    |
| 3    |   example-3    |
-------------------------

类别表,例如:

-------------------------
| categories            |
-------------------------
| id   |  name          |
-------------------------

和一个联结表,如:

---------------------------------
| company_categories            |
---------------------------------
| company_id   |  category_id   |
---------------------------------

当前代码:

此代码有效,但远没有效率。

DELIMITER $$
 DROP PROCEDURE IF EXISTS fill_junc_table$$
 CREATE PROCEDURE fill_junc_table()
 BEGIN
 DECLARE r  INT;
 DECLARE i  INT;
 DECLARE i2  INT;
 DECLARE loop_length  INT;
 DECLARE company_old_len  INT;
 DECLARE _href  VARCHAR(255);
 DECLARE cat_id  INT;
 DECLARE comp_id  INT;

 SET r = 0;
 SET i = 0;
 SET company_old_len = 0;
 SELECT COUNT(*) INTO loop_length FROM companies;

 WHILE i  < loop_length DO
  SELECT href INTO _href FROM company_old LIMIT i,1;
  SELECT id INTO comp_id FROM companies WHERE site_href=_href;
  SELECT COUNT(*) INTO company_old_len FROM company_old WHERE href=_href;
  SET i2 = 0;
  WHILE i2  < company_old_len DO
   SELECT category_id INTO cat_id FROM company_old WHERE href=_href LIMIT i2,1;
   INSERT INTO company_categories (company_id, category_id) VALUES (comp_id, cat_id);
   SET  r = r + 1;
   SET  i2 = i2 + 1;
  END WHILE;
  SET  i = i + 1;
 END WHILE;

 SELECT r;
 END$$
DELIMITER ;

CALL fill_junc_table();

编辑(新想法):

我将通过使用以下列完全复制companies_1表来测试解决此问题的另一种方法(在复制时company_id为空):

---------------------------------------------
| company_id   | category_id  |  name       |
---------------------------------------------

然后,我将遍历companies_2表以填充与name-column相关的正确company_id。

我希望你能对此有所了解。当我完成测试时,我会将结果留给其他人。

2 个答案:

答案 0 :(得分:2)

为了澄清,我在show(input - '0'); show(input - 48); 中看不到任何PIVOT转换。我看到的是您想要JUNCTION TABLE,因为似乎company_categoriescompanies表格有categories关系。

在您的情况下,您有many-to-many 多个 company。您还categories分配给多个 categories

现在根据您的要求:

  

我想从表companies_1中移动类别的链接   进入company_categories表。 company_id在   company_categories表需要等于companies_2的id   表。 companies_1和companies_2表的记录是   由“name”-column链接。

我带着这个问题到达了:

companies

如果有效,请告诉我。您创建的嵌套循环将需要一段时间。

正如@DanielE指出的那样,这个查询将假设INSERT INTO company_categories (company_id, category_id) SELECT C2.id , C1.category_id FROM companies_1 C1 INNER JOIN companies_2 C2 ON C2.name = C1.name 为空。否则我们将需要使用company_categories

答案 1 :(得分:2)

为什么不直接更新companies_1?

ALTER TABLE companies_1 ADD (company_id INT)
UPDATE companies_1 SET company_id = (SELECT id FROM companies_2 WHERE name=companies_1.name)
ALTER TABLE companies_1 DROP name, RENAME TO company_categories
SELECT * FROM `company_categories` 

输出

id  category_id company_id  
1   1           1
2   2           1
3   1           2
4   2           2
5   3           2
6   1           3