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