开发者

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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜