简体   繁体   中英

Finding a preferred result from sorted query

I have a table that contains address information (called Address_Link) for people, where one person can have multiple addresses. Address_Link has some of the following fields:

  • ID (primary key)
  • PersonID (foreign key to the table containing info on the person)
  • CountryID (foreign key to the table with country information)
  • Street_Address

A query I'm building needs only one address per person, but the users of my application care about which address shows up. There is actually a small hierarchy of preferred countries - Canada first, then the UK, then everyone else. (So, if someone has two addresses, one in Australia and one in the UK, the UK address should be the one to appear.)

Currently there's a query in the Access application that sorts and outputs this table's contents along with a "Sort_Value" column that assigns an address in Canada with a value of 0, UK 1, and everyone else 2.

Some queries I am working on need this preference included, but I am having difficulty making the query pull the correct address. Someone with Australia and the UK will have the Australian address appear instead. I had been using "First" to pull the Street_Address, but this is incorrect. Using "Min" doesn't seem to do the trick either.

For a given PersonID, how do I grab the address entry with the lowest value in the Sort_Value column in Access?

(EDIT) Here is the SQL that runs, albeit very slowly:

SELECT a.PersonID, b.CountryID
FROM Address_link AS a LEFT JOIN Countries AS b ON a.CountryID = b.ID
WHERE a.PersonID = (SELECT TOP 1 ID from Addresses_Sorted WHERE PersonID = a.PersonID)
ORDER BY a.PersonID;

The country name isn't stored in the Address, only the Country ID. There is a separate table for country-specific information.

You said Address_Link.PersonID is a "foreign key to the table containing info on the person." I will pretend that other table is named people_table and its PersonID values are unique within the table.

If that is correct, start from that table and use a correlated subquery to retrieve the Address_Link.ID from the row you want for each PersonID .

SELECT
    y.PersonID,
    (
        SELECT TOP 1 ID
        FROM Address_Link
        WHERE PersonID = y.PersonID
        ORDER BY
            Switch
                (
                    CountryID = 'CA', 0,
                    CountryID = 'UK', 1,
                    True, 2
                ),
            ID
        ) AS target_ID
FROM people_table AS y;

I guessed that CountryID is text datatype. If it's actually numeric, revise the Switch expression.

Once you have your version of the query working to return the correct PersonID and ID combinations, INNER JOIN that query back to Address_Link to select only the matching rows.

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