简体   繁体   中英

MySQL: Join records 1:1 that have a one to many relationship

I have a table that contains properties and their types:

INSERT INTO properties (property_id, year_built, type_id, code)
VALUES 
(1, 2000, 3, 'ABC'),
(2, 2001, 3, 'ABC'),
(3, 2002, 3, 'ABC'),
(4, 2003, 3, 'ABC'),
(5, 2004, 3, 'ABC'),
(6, 2005, 3, 'ABC'),
(7, 2000, 3, 'DEF'),
(8, 2001, 3, 'DEF'),
(9, 2002, 3, 'DEF'),
(10, 2003, 3, 'DEF'),
(11, 2004, 3, 'DEF'),
(12, 2005, 3, 'DEF'),
(13, 2000, 3, 'GHI'),
(14, 2001, 3, 'GHI'),
(15, 2002, 3, 'GHI'),
(16, 2003, 3, 'GHI'),
(17, 2004, 3, 'GHI'),
(18, 2005, 3, 'GHI');

I have a second table 'agents' with the same number of records as the properties table.

INSERT INTO agents (agent_id, year_built, type_id)
VALUES 
(50, 2000, 3),
(51, 2001, 3),
(52, 2002, 3),
(53, 2003, 3),
(54, 2004, 3),
(55, 2005, 3),
(56, 2000, 3),
(57, 2001, 3),
(58, 2002, 3),
(59, 2003, 3),
(60, 2004, 3),
(61, 2005, 3),
(62, 2000, 3),
(63, 2001, 3),
(64, 2002, 3),
(65, 2003, 3),
(66, 2004, 3),
(67, 2005, 3);

There is a field in the properties table: 'agent_id' that should be populated with a single agent of the same year and type. For example, this is the expected result of the properties table for the year 2000 after running an update statement:

SELECT (*) FROM properties WHERE year_built = 2000;
property_id  year_built  type_id  code  agent_id
1            2000        3        ABC   50
7            2000        3        DEF   56
13           2000        3        GHI   62

Every join that I try results in all matching agent records returned for each property_id. For example:

SELECT properties.*, agents.agent_id
FROM   properties
JOIN   agents
       USING(year_built, type_id)
WHERE  properties.year_built = 2000;

Would give the result:

property_id  year_built  type_id  code  agent_id
1            2000        3        ABC   50
1            2000        3        ABC   56
1            2000        3        ABC   62
7            2000        3        DEF   50
7            2000        3        DEF   56
7            2000        3        DEF   62
13           2000        3        GHI   50
13           2000        3        GHI   56
13           2000        3        GHI   62

I'm aware that a simple join will return all the agent records, but I'm not sure how to match a single agent record to a single properties record with just the fields I have to work with. In addition, I would want these to be ordered - so that the first property_id for a year/type matches with the first agent_id of the same year/type. I should also add that neither table's fields, keys, or properties can be modified.

As the data from table properties can be evenly matched to the data from table agents , we can capitalize on the row number added to each table for precise matching. This is written and tested in workbench using MySQL5.7 :

select p.property_id,p.year_built,p.type_id,p.code,agent_id from 
    (select property_id,year_built,type_id,code,@row_id:=@row_id+1 as rowid 
    from properties,(select @row_id:=0) t ) p
join 
    (select agent_id,year_built,type_id,@row_number:=@row_number+1 as rownumber 
    from agents,(select @row_number:=0) t ) a
on p.year_built=a.year_built and p.type_id=a.type_id and p.rowid=a.rownumber
where p.year_built=2000
;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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