How do I do a mysql join and limit the number of identical results for the leftmost table to 1?
My query looks like this
SELECT DISTINCT
addr.`Linje-ID` as lineid,
开发者_开发百科 addr.`Sluttbruker` as companyname,
addr.`Gate` as street,
addr.`Husnr` as housenr,
addr.`Postnr` as zip,
addr.`Poststed` as location,
loc.`UX_KOORDINAT` as coord_x,
loc.`UY_KOORDINAT` as coord_y,
loc.`ADRESSE_ID` as addr_id
FROM
addresses addr INNER JOIN
locationdata loc ON
loc.`POSTSTED` = addr.`Poststed` AND
loc.`POST_NR` = addr.`Postnr` AND
loc.`GATENAVN` = UPPER(addr.`Gate`) AND
loc.`HUSNUMMER` = addr.`Husnr`
The goal is for the query to return EVERY result in "addresses" with matching data from "locationdata" for each one. This query does that, but it also duplicates the result from "addresses" for every additional match it finds in "locationdata".
How can I change my query to return only all the rows in "addresses" (`Linje-ID` is the unique identifier)
You need to decide what to do about multiple values being returned for a given addresses row by wrapping the columns from the locationdata table in aggregate functions. Here I assumed you simply wanted the minimum value:
Select addr.Linje-ID as lineid
, addr.Sluttbruker As companyName
, addr.Gate As street
, addr.Husnr As housenr
, addr.postnr As zip
, addr. poststed As location
, Min( loc.UX_KOORDINAT ) As coord_x
, Min( loc.UY_KOORDINAT ) As coord_y
, Min( loc.adresse_id ) As addr_id
From addresses As addr
Join locationdata As loc
On loc.poststed = addr.poststed
And loc.post_nr = addr postnr
And loc.gatnavn = upper(addr.gate)
And loc.husnummer = addr.husnr
Group By addr.Linje-ID
, addr.Sluttbruker
, addr.Gate
, addr.Husnr
, addr.postnr
, addr. poststed
Addition
Another solution, which would produce more logical results than above (although no more logical without more information) would be to arbitrarily choose a locationdata row for each address. To do that, we need to know the names of the Primary Key columns. Here I assumed they were called "PrimaryKeyColumn"
Select addr.Linje-ID as lineid
, addr.Sluttbruker As companyName
, addr.Gate As street
, addr.Husnr As housenr
, addr.postnr As zip
, addr. poststed As location
, loc.UX_KOORDINAT As coord_x
, loc.UY_KOORDINAT As coord_y
, loc.adresse_id As addr_id
From addresses As A
Join (
Select addr.PrimaryKeyColumn
, Min( loc.PrimaryKeyColumn ) As locid
From addresses As addr
Join locationdata As loc
On loc.poststed = addr.poststed
And loc.post_nr = addr postnr
And loc.gatnavn = upper(addr.gate)
And loc.husnummer = addr.husnr
Group By addr.PrimaryKeyColumn
) As Z
On Z.PrimaryKeyColumn = addr.PrimaryKeyColumn
Join locationdata As loc
On loc.PrimaryKeyColumn = Z.locid
SELECT
addr.`Linje-ID` as lineid,
addr.`Sluttbruker` as companyname,
addr.`Gate` as street,
addr.`Husnr` as housenr,
addr.`Postnr` as zip,
addr.`Poststed` as location,
loc.`UX_KOORDINAT` as coord_x,
loc.`UY_KOORDINAT` as coord_y,
loc.`ADRESSE_ID` as addr_id
FROM
addresses addr INNER JOIN
locationdata loc ON
loc.`POSTSTED` = addr.`Poststed` AND
loc.`POST_NR` = addr.`Postnr` AND
loc.`GATENAVN` = UPPER(addr.`Gate`) AND
loc.`HUSNUMMER` = addr.`Husnr`
GROUP BY addr.`Linje-ID`
ANSI-SQL compliant
SELECT
addr.Linje-ID as lineid,
addr.Sluttbruker as companyname,
addr.Gate as street,
addr.Husnr as housenr,
addr.Postnr as zip,
addr.Poststed as location,
loc.UX_KOORDINAT as coord_x,
loc.UY_KOORDINAT as coord_y,
loc.ADRESSE_ID as addr_id
FROM (
SELECT
addr.Linje-ID as lineid,
addr.Sluttbruker as companyname,
addr.Gate as street,
addr.Husnr as housenr,
addr.Postnr as zip,
addr.Poststed as location,
(SELECT MIN(ADRESSE_ID) ADRESSE_ID
FROM locationdata loc
WHERE loc.POSTSTED = addr.Poststed AND
loc.POST_NR = addr.Postnr AND
loc.GATENAVN = UPPER(addr.Gate) AND
loc.HUSNUMMER = addr.Husnr)
FROM addresses addr
) ADDR
INNER JOIN locationdata loc ON loc.ADRESSE_ID = ADDR.ADRESSE_ID
精彩评论