Mysql 多对多对多的分组关系
我有一个要求,根据此人当时居住的国家,将税率映射到此人Mysql 多对多对多的分组关系,mysql,sql,Mysql,Sql,我有一个要求,根据此人当时居住的国家,将税率映射到此人 tbl: person | p_id | name_first | name_last | =======++======================== | 1 | john | smith | | 2 | joanne | smyth | tbl: person_in_country | p_id | iso | arrived
tbl: person
| p_id | name_first | name_last |
=======++========================
| 1 | john | smith |
| 2 | joanne | smyth |
tbl: person_in_country
| p_id | iso | arrived |
===========================
| 1 | GB | 1980-01-01 |
| 2 | FR | 1987-03-21 |
| 1 | FR | 2003-06-17 |
| 1 | JP | 2008-07-02 |
| 2 | GB | 2008-10-01 |
| 1 | GB | 2009-01-10 |
tbl: country
| iso | ctry_name |
========================
| GB | United Kingdom |
| FR | France |
| JP | Japan |
tbl: tax_rates
| iso | tax_rate | tax_date |
===============================
| GB | 17.5 | 1970-01-01 |
| FR | 15.0 | 1977-03-21 |
| JP | 12.0 | 1977-06-17 |
| FR | 15.0 | 1994-03-21 |
| JP | 18.5 | 2008-07-02 |
| GB | 15 | 2008-04-01 |
| GB | 20 | 2010-05-01 |
所以我需要一个元组,包含这个国家的人和他们在给定时间应该拥有的税率
大致如下:
select p.p_id, p.name_first, p.name_last,
pic.arrived,
c.iso, c.ctry_name,
t.tax_rate
from people p
left join (select * from person_in_country order by arrived desc) pic using (p_id)
left join country c on c.iso = pic.iso
left join (select * from tax_rates order by tax_date desc) t on t.iso = c.iso
where t.tax_date <= NOW()
group by p.pid, pic.arrived, t.tax_date
希望这有意义。。。提前多谢事实上,您必须分三步基本完成查询。首先,您将检索一种包含所有所需列的原始数据,连接相关表,无论这些列将用于连接或检索choosen数据 之后,您必须对数据进行分组,以便只从匹配的联接中转到最后的日期 最后,您必须再次查询tax表,以检索到达时当前纳税日期的税款 有可能有一种更简单或更优雅的方法来实现这一点,但这个查询正在运行。根据查询命令检查系统性能。乍一看似乎有点难,但仔细一看就不难了。SQL代码:
SELECT
c02.iso,
c02.p_id,
c02.name_first,
c02.name_last,
c02.ctry_name,
c02.arrived,
c02.mtax_date,
tax_rates.tax_rate
FROM (
SELECT
c01.iso,
c01.p_id,
c01.name_first,
c01.name_last,
c01.ctry_name,
c01.arrived,
Max(c01.tax_date) AS mtax_date
FROM (
SELECT
country.iso,
person.p_id,
person.name_first,
person.name_last,
country.ctry_name,
person_in_country.arrived,
tax_rates.tax_date
FROM
tax_rates
INNER JOIN (
country
INNER JOIN (
person
INNER JOIN
person_in_country
ON
person.p_id = person_in_country.p_id
)
ON
country.iso = person_in_country.iso
)
ON
tax_rates.iso = person_in_country.iso
GROUP BY
country.iso,
person.p_id,
person.name_first,
person.name_last,
country.ctry_name,
person_in_country.arrived,
tax_rates.tax_date
HAVING (((tax_rates.tax_date)<=[arrived]))
) as c01
GROUP BY
c01.iso,
c01.p_id,
c01.name_first,
c01.name_last,
c01.ctry_name,
c01.arrived
) as c02
INNER JOIN
tax_rates ON (
c02.mtax_date = tax_rates.tax_date
)
AND
(
c02.iso = tax_rates.iso
);
如果你喜欢,考虑下面简单的两步行动:1。如果您还没有这样做,请提供适当的DDL和/或SQLFIDLE,以便我们可以更轻松地复制问题。2.如果您还没有这样做,请提供与步骤1中提供的信息相对应的所需结果集。还有一个提示:SQL也是一种语言,请尽可能多地使用缩进;
iso p_id name_first name_last ctry_name arrived mtax_date tax_rate
GB 1 john smith United Kindom 01/01/1980 01/01/1970 18
FR 2 joanne smyth France 21/03/1987 21/03/1977 15
FR 1 john smith France 17/06/2003 21/03/1994 15
JP 1 john smith Japan 02/07/2008 02/07/2008 18
GB 1 john smith United Kindom 10/01/2009 01/04/2008 15
GB 2 joanne smyth United Kindom 01/10/2008 01/04/2008 15