'Lookup multiple values from one ID or product type
I have a requirement to lookup a predefined list of value countries for specific IDs or products.
This is a one to many or in some cases many to many relationship, so a simple CASE statement cannot suffice.
For example, when selecting ID 24553489 it should return a list of 5 valid countries associated with that ID. And so on for other examples, the list can be one or many.
How would I approach this in sql? I am thinking the easiest way is to create a linked table and use that to create the mapping but there may be an easier way.
Can anyone suggest the best way to approach this?
Edit: So for example...
24553489 should only be linked with UK, South Africa, Spain, Italy, France
23343097 should only be linked with South Africa, Spain, Italy
Etc
Thanks.
Solution 1:[1]
I can't tell if you're comfortable with the many to many table, please forgive me if I'm stating the obvious - but here is an example of how to do it and a couple of examples of how to use it. Note that I set up a couple of CTEs to represent your existing data (country table and products table), and then a CTE to represent the map that holds the many to many relationship. After that I defined 2 examples, one showing how to use the map to go from a product to countries, and the other to show how to go from a country to products.
Feel free to post in comments if you want further clarification!
with cteProducts as ( --You should already have a Products table
SELECT *
FROM (VALUES (100, 'Gizmos'), (101, 'Widgets'), (102, 'Thingies')
) as Products(ProductID, ProductName)
), cteCountries as ( --And already have a Country table
SELECT *
FROM (VALUES ('UK', 'United Kingdom'), ('SA', 'South Africa'), ('SP', 'Spain'), ('IT', 'Italy'), ('FR', 'France')
) as Countries(CountryCode, CountryName)
), cteMap as ( --Make a map table that handles the many to many relationship
SELECT *
FROM (VALUES (100, 'UK'), (100, 'SA'), (100, 'IT')
, (101, 'SA'), (101, 'SP'), (101, 'IT')
, (102, 'UK'), (102, 'SP')
) as ProdMap(ProductID, CountryCode)
), cteProdInSpain as ( -- To use it, you can look for products available in a country
SELECT P.*
FROM cteProducts as P
INNER JOIN cteMap as M on M.ProductID = P.ProductID
INNER JOIN cteCountries as C on C.CountryCode = M.CountryCode
WHERE C.CountryName = 'Spain'
), cteWhereBuy as ( -- or where to buy a product
SELECT P.ProductName, C.CountryName
FROM cteCountries as C
INNER JOIN cteMap as M on M.CountryCode = C.CountryCode
INNER JOIN cteProducts as P on P.ProductID = M.ProductID
WHERE P.ProductName = 'Gizmos'
)
--SELECT * FROM cteWhereBuy
SELECT * FROM cteProdInSpain
Solution 2:[2]
Thank you all for responses, but I ended up creating a mapping and populating a table from a combination of a cursor and if statements. This is not ideal but without getting too complex this is the only way I could do this.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Robert Sheahan |
| Solution 2 | Grant Doole |
