简体   繁体   English

当外键不同时,如何在MySQL中将主键连接到两个外键?

[英]How to join a primary key to two foreign keys in MySQL when the foreign keys will be different?

So, my problem is this: I work with a sales company and am developing an app using MS Access 2007 as a front-end with MySQL 5.6 Server as the back-end. 所以,我的问题是这样的:我与一家销售公司合作,并且正在使用MS Access 2007作为前端,以MySQL 5.6 Server作为后端来开发应用程序。 I'm trying to generate a view that calculates commission data for each rep. 我正在尝试生成一个视图,该视图计算每个代表的佣金数据。

My DDLs are as follows: 我的DDL如下:

CREATE TABLE emp_employees
    (`id` int, `tsr_code` int, `first_name` varchar(9), `location_id` int)
;

INSERT INTO emp_employees
    (`id`, `tsr_code`, `first_name`, `location_id`)
VALUES
    (47, 829, 'ELIZABETH', 6),
    (199, 818, 'ERIC', 6),
    (1642, 301, 'JACK', 4),
    (2346, 619, 'SHANNA', 5),
    (2386, 899, 'MICHAEL', 3),
    (2490, 590, 'KARRIE', 4),
    (2642, 386, 'MINDI', 3),
    (2914, 615, 'REMELL', 3),
    (3150, 025, 'TEAL', 3),
    (3156, 609, 'JESSICA', 5)
;


CREATE TABLE x_recap
    (`recap_id` int, `sale_date` datetime, `location_id` int, `tsr_id` int, `ver_id` int, `tsr_cpo` decimal(10,4), `ver_cpo` decimal(10,4))
;

INSERT INTO x_recap
    (`recap_id`, `sale_date`, `location_id`, `tsr_id`, `ver_id`, `tsr_cpo`, `ver_cpo`)
VALUES
    (423670, '2017-01-23 08:15:44', 5, 3156, 2346, 9.0000, 1.5000),
    (423671, '2017-01-23 08:16:03', 6, 199, 47, 13.5000, 1.5000),
    (423672, '2017-01-23 08:16:41', 3, 3150, 2914, 4.7500, 0),
    (423673, '2017-01-23 08:17:08', 3, 2386, 2642, 8.7500, 1.50),
    (423674, '2017-01-23 08:17:28', 5, 2346, 2346, 5.7500, 0.50)
;

Desired result: 所需结果:

+------------+-------------+------------+----------+----------+
| sale_date  | location_id | first_name | tsr_comm | ver_comm |
+------------+-------------+------------+----------+----------+
| 2017-01-23 |           3 | MICHAEL    |   8.7500 |   0.0000 |
| 2017-01-23 |           3 | MINDI      |   0.0000 |   1.5000 |
| 2017-01-23 |           3 | REMELL     |   0.0000 |   0.0000 |
| 2017-01-23 |           3 | TEAL       |   4.7500 |   0.0000 |
| 2017-01-23 |           5 | JESSICA    |   9.0000 |   0.0000 |
| 2017-01-23 |           5 | SHANNA     |   5.7500 |   2.0000 |
| 2017-01-23 |           6 | ELIZABETH  |   0.0000 |   1.5000 |
| 2017-01-23 |           6 | ERIC       |  13.5000 |   0.0000 |
+------------+-------------+------------+----------+----------+

and SQL Fiddle of same . 和SQL Fiddle相同

EDIT (2017-12-13): Notice how employee 2346, "Shanna", has one verify (recap_id=423670) for $1.50. 编辑(2017-12-13):请注意,员工2346如何使用$ 1.50进行一次验证(recap_id = 423670),即``Shanna''。 She also has a self-verified sale (recap_id=423674) for another $.50 in verify commission and $5.75 for the sale. 她还进行了一次自我验证的交易(recap_id = 423674),需要另外支付$ .50的验证佣金和$ 5.75的交易。 These have to be kept track of separately. 这些必须分开跟踪。

As you can see from the Fiddle, I can get the data to appear the way I want it by using a Union query. 从小提琴中可以看到,我可以通过使用Union查询使数据以我想要的方式显示。 The problem becomes when I load in 4100 employee records and 236K sale entries on the "recap". 当我在“摘要”中加载4100名员工记录和236K销售条目时,问题就变成了。 Having read up, I understand that my query now takes so long (about 30 seconds) because MySQL is creating a temporary table from the union and then preforming the outer query from the un-indexed temp table. 阅读后,我了解到我的查询现在花费了很长时间(约30秒),因为MySQL正在根据联合创建临时表,然后根据未索引的临时表执行外部查询。 The time drastically decreases when I add a WHERE clause to each of the Unions. 当我向每个Union添加WHERE子句时,时间将大大减少。

I feel there has to be something that I'm missing: a special inner join, something. 我觉得必须缺少一些东西:特殊的内部联接,某些东西。 I'm still fairly new to MySQL even though I use it everyday (my job usually only requires some concat() with an occasional inner join). 即使我每天都使用MySQL,我还是相当陌生的(我的工作通常只需要一些concat()并偶尔进行内部联接)。 I'm open to just about anything. 我几乎对任何事情都开放。 I'm not beyond partially redesigning my tables if that turns out to be the best option (and maybe a little community help). 如果事实证明这是最好的选择,我将不做部分重新设计表 (也许会得到一些社区帮助)。

GOAL: For each employee in the emp_employees table, I need to get the sum of the tsr_cpo field (sum(RECAP.tsr_cpo) where EMP.id = RECAP.tsr_id). 目标:对于emp_employees表中的每个雇员,我需要获取tsr_cpo字段的总和(sum(RECAP.tsr_cpo),其中EMP.id = RECAP.tsr_id)。 I also need to get the sum of ver_cpo for anyone who verified a sale (sum(RECAP.ver_cpo) where EMP.id = RECAP.ver_id). 对于验证销售的任何人,我还需要获取ver_cpo的总和(sum(RECAP.ver_cpo),其中EMP.id = RECAP.ver_id)。

I looked over your question and I agree that it would seem very expensive and difficult to maintain a bunch of UNION queries to create the "Desired Result" mentioned above. 我仔细考虑了您的问题,并同意维持一堆UNION查询来创建上述“所需结果”似乎非常昂贵且困难。

EDIT 12-14-2017: Per your comment to my answer, I've made a few changes below. 编辑12-14-2017:根据您对我的回答的评论,我在下面进行了一些更改。

I think this can be accomplished in two fairly simple queries. 我认为可以通过两个非常简单的查询来完成。 The first query, named qry_Comms , has the following SQL code: 第一个查询名为qry_Comms ,具有以下SQL代码:

SELECT x_recap.sale_date, emp_employees.location_id, emp_employees.id, emp_employees.first_name, Sum(x_recap.tsr_cpo) AS tsr_comm, 0 AS ver_comm
FROM x_recap INNER JOIN emp_employees ON x_recap.tsr_id = emp_employees.id
GROUP BY x_recap.sale_date, emp_employees.location_id, emp_employees.id, emp_employees.first_name, 0
UNION ALL 
SELECT x_recap.sale_date, emp_employees.location_id, emp_employees.id, emp_employees.first_name, 0 AS tsr_comm, Sum(x_recap.ver_cpo) AS ver_comm
FROM x_recap INNER JOIN emp_employees ON x_recap.ver_id = emp_employees.id
GROUP BY x_recap.sale_date, emp_employees.location_id, emp_employees.id, emp_employees.first_name, 0;

And then the second query, named qry_TotalComms , has the following SQL Code: 然后第二个查询名为qry_TotalComms ,具有以下SQL代码:

SELECT qry_Comms.sale_date, qry_Comms.location_id, qry_Comms.first_name, Sum(qry_Comms.tsr_comm) AS SumOftsr_comm, Sum(qry_Comms.ver_comm) AS SumOfver_comm
FROM qry_Comms
GROUP BY qry_Comms.sale_date, qry_Comms.location_id, qry_Comms.first_name, qry_Comms.id;

The qry_Comms query is the base query to get all the data needed, and the second query, qry_TotalComms , should group all the data together properly. qry_Comms查询是获取所有所需数据的基础查询,第二个查询qry_TotalComms应该将所有数据正确组合在一起。 So all you should have to do is save both of these queries in your Access database and then run the qry_TotalComms query. 因此,您要做的就是将这两个查询都保存在Access数据库中,然后运行qry_TotalComms查询。 I think that should provide the correct results, per your "Desired Results" table above (and your comment to my original answer). 我认为,应该按照上面的“所需结果”表(以及您对我的原始答案的评论)提供正确的结果。

Also, if these queries still do not execute fast enough, try using an MS Access "Pass-Through" query for the qry_Comms query, which is one of the MS Access Query types that can be chosen on the "Query Design" Ribbon menu. 另外,如果这些查询仍不能足够快地执行,请尝试对qry_Comms查询使用MS Access“直通”查询,这是可以在“查询设计”功能区菜单上选择的MS Access查询类型之一。 An Access "Pass-Through" query sends the SQL code directly to the database server and lets the server do the processing and just returns the resulting recordset. 访问“通过”查询将SQL代码直接发送到数据库服务器,并让服务器进行处理,并仅返回结果记录集。 All other types of Access queries will actually copy the table data all down locally and then create the resulting data set locally, which can be slow and expensive if you're dealing with big tables. 实际上,所有其他类型的Access查询都将本地复制表数据,然后在本地创建结果数据集,如果要处理大表,这可能会很慢且很昂贵。 So when using MySQL or SQL Server with Access, "Pass-Through" queries can greatly improve your Access application performance. 因此,当将MySQL或SQL Server与Access一起使用时,“传递”查询可以大大提高Access应用程序的性能。

Lastly, you could also create the above queries I provided as views on your MySQL database, and then just call the qry_TotalComms view directly from Access. 最后,您还可以在MySQL数据库上创建我作为视图提供的上述查询,然后直接从Access调用qry_TotalComms视图。 That would be a second alternative to possibly improving performance of the query I've given above. 这将是可能改善我上面给出的查询性能的第二种选择。

Anyway, I hope this information helps, but please let me know if you have any questions about this and I will do my best to help solve the problem! 无论如何,我希望这些信息能对您有所帮助,但是如果您对此有任何疑问,请告诉我,我们将尽力帮助解决该问题!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM