Multiple level lookup field - sql

I have three tables, Countries, Department & Cities, Cities table contains a foreign key to Department table PK index, and Department contains a foreign key to Countries Table PK Index for example :
COUNTRIES TABLE RECORDS
PK=1 | NAME = France
DEPARTMENTS TABLE RECORDS
PK=1 | NAME=Ile de France | COUNTRYKEY=1
PK=2 | NAME=Bouches du Rhone | COUNTRYKEY=1
CITIES TABLE RECORDS
PK=1 | NAME=Paris | DEPTKEY=1
PK=2 | NAME=Marseille | DEPTKEY=2
So, i want display a city form with all details, name department country
I actually use lookup field to display the department name but what about to display also in the city form the "COUNTRY" name which is only included on Department Table as foreignkey ??? i mean is there a way to display a lookup field of a lookup field ? as a beginner a detailled code would be appreciated, Thanks to all

SELECT d.NAME AS Department_Name, ct.NAME as CITY, cn.NAME AS COUNTRY
FROM DEPARTMENTS d
LEFT JOIN CITIES ct ON d.PK = ct. DEPTKEY
LEFT JOIN COUNTRIES ON d.COUNTRYKEY = cn.PK
You might need an WHERE clause added and possibly a ORDER BY at the end, but you didn't indicate that.

Related

PostgreSQL parse countries in array against the countries table

We have content and country tables.
Country is pretty simple:
country_name column defined as string:
Albania,
Belgium,
China,
Denmark etc...
Content is a table with half a million of rows with various data with countries column defined as array text[]. Each value there has a number of countries concatenated like:
{"denmark,finland,france,germany,ireland,gb,italy,netherlands,poland,russia,spain,sweden,australia,brazil,canada,china,india,indonesia,japan,malaysia,vietnam,mexico,"south korea",thailand,usa,singapore,uae"}
The update from internal team is for a thousand of records and we are not sure if countries are all spelled correctly. So the task is to reconcile against the country_name in country table.
I am doing replace(replace(country_array::text,'{',''),'}','') as country_text and think about doing UNPIVOT to check each column against country table.
Is there any other easier way to make sure countries array in Content table has valid country names from country table?
Thank you
You can unnest() each array to a set of rows, and ensure that all values occur in the country table. The following query gives you the array elements that are missing in the reference table:
select *
from
content c
cross join lateral unnest(c.countries) as t(country_name)
left join country y on y.country_name = t.country_name
where y.country_name is null
Demo on DB Fiddle
country table:
id | country_name
-: | :-----------
1 | albania
2 | denmark
content table:
id | countries
-: | :----------------
1 | {albania,denmark}
1 | {albania,france}
query results:
id | countries | country_name
-: | :--------------- | :-----------
1 | {albania,france} | france
If you have doubts about some countries not being spelled correctly, then no doubt there are such examples.
Start by getting the list of countries that are not in the reference table:
select c_country, count(*)
from content c cross join lateral
unnnest(c.countries) c_country left join
countries co
on co.country_name = c_country
where co.country_name is not null
group by c_country
order by count(*) desc;
Then, you can go in and fix the data.
There is nothing wrong a priori with storing values in arrays. However, if you were designing the database from scratch, I would probably recommend a contentCountries table and a countryId. That would ensure unambiguous relationships.
In your case, you should probably fix the ingestion process so the values are known to be correct when input. That might be sufficient, given that you already have a lot of data and just need to fix it.

Update in join query with 3 tables

I have problem with updating query in Access. I have 3 tables:
City
ID | CityName | CountryID|
Country
ID | CountryName
CityImport
City | Country
I'm not sure if it's the right design, but it's of a lesser importance now.
I want to update my db with Excel data. I decided to create CityImport table to make the process clearer. I put city information in this table and I want fill City table with it. When I run a query like UPDATE (CityImport INNER JOIN Country ON CityImport.Country = Country.CountryName) LEFT JOIN City ON City.CityName = CityImport.City AND City.CountryID = Country.ID SET City.CityName = CityImport.City, City.CountryID = Country.ID WHERE CityImport.City IS NOT NULL, I get JOIN expression not supported error.
I thought it was a problem with my syntax, but if I remove one condition from JOIN, and leave it as UPDATE (CityImport INNER JOIN Country ON CityImport.Country = Country.CountryName) LEFT JOIN City ON City.CityName = CityImport.City SET City.CityName = CityImport.City, City.CountryID = Country.ID WHERE CityImport.City IS NOT NULL, it works fine. The problem is that it ignores cities with the same name in different countries.
Is it possible to make such join work properly somehow? Or is it incorrect by definition? It requires to join one one table with another join results on two columns from different tables. I could probably work around it somehow in this case, but I want to use the same method for more, more complicated tables.
I played around with different takes on this query for few hours, googled hundred times, but still no success.
The first problem I can see is that you're using UPDATE to insert data into a table. You should be using INSERT INTO.
Starting with this table:
You'll need to insert the unique Country names into the country table first:
INSERT INTO Country (Country)
SELECT DISTINCT Country
FROM CityImport
This will give you this table:
Now you need to populate the City table with city names and the ID's from the Country table:
INSERT INTO City (CityName, CountryID)
SELECT City, Country.ID
FROM CityImport INNER JOIN Country ON CityImport.Country = Country.Country
This returns this table:
Edit:
Table Structure:
CityImport
City - Text
Country - Text
Country
ID - AutoNumber
Country - Text
Primary Key: ID
City
ID - AutoNumber
CityName - Text
CountryID - Number
Primary Key: ID
Foreign Key CountryID References Country

Insert a value based on id from two different tables

I got a huge question.
I'm trying to migrate some data from an existent table to a new one. I'm having troubles to figure out how to do the following :
In the Address table there are two columns:
AddressTable
---------------------------------------------
StateCode(nvarchar) and CountryCode(nvarchar)
Both hold a two letter code for states and countries codes.
Now in the new table we made two foreign keys
NewAddressTable
---------------------
StateId and CountryId
That correspond to two tables State and Country
StateTable has (Id,(FK)IdCountry,Name,Code)
CountryTable has (Id,Name,Code)
What I'm trying to do is based on the state and country code on the Address table how can I add replace the values from the old table with the new ones based on the state and code.
An example:
AddressTable
-------------
City StateCode PostalCode CountryCode
North Haven CT 06473 US
NewAddressTable
---------------
IdCountry IdState
236 8
CountryTable
---------------
Id Name Code
236 UNITED STATES US
StateTable
--------------
Id IdCountry Name Code
8 236 CONNECTICUT CT
Thank you.
Something like this should work.
insert into newtable
(idCountry, idState)
select country.id, state.id
from oldtable join country on oldtable.CountryCode = Country.Code
join state on oldtable.stateCode = state.code

Joining Three tables without a matching column

I want to create a geography dimension using ssis 2008.I have 3 table sources.
Here is the explanation
Table 1 = Country: country code and country name
Table 2 = Post code: post code and city name
Table 3 = Territory : Territory code and Territory name
Here is how data looks
[Table 1= Country]
code name
------------------
US | United states
CA | Canada
[Table 2= post code]
Code city
---------------
1000 | Paris
2000 | Niece
[Table 3= Territory]
Code name
----------------
N | North
S | south
As you can see there is no single common column, I want to group these 3 tables in the same geography dimension.
So, how can I do it ?
Also,The use of this geography dim will be when another dimension for example customer dimension.we want to know the revenue of client according to his geography or the the top salespersons in some city.
and in both customer and salesperson tables you can find the those 3 as foreign keys.
You don't need a "common column" shared by all three tables.
You do need a "column column" between each pair of tables. How else are you going to link them???
Q: Is there any column that links "Country" to "City"? You should have a "country code" column in "city".
Q: Is there any way to link "Territory" with either "post code" or "country"? If "Yes": problem solved. Please list the fields. If "No" ... then you need to change your schema.
Based on you comment to paulsm4 you then want to use those tables that hold the linking information to join to each of the above 3 tables.
On the other hand if you really want to join just those three tables
select * from Country
full outer join [Post code]
on 'a' = 'a'
full outer join Territory
on 'b' = 'b'
create table dim.geography (geoID int,citycode int, countrycode char(2),territorycode char(1))
insert into dim.geography (select city as citycode,country as countrycode, territory as territorycode from Customer union select city, country,territory from salesperson)
Assuming here that Customer and salesperson tables hold the codes and not the values for country,territory, and country.
The code above will build a dimension for the geography you want. Of course if you add any additional unique city,country,territory codes into the customer/salesperson tables you will need to add it to your dimension. This is just an initial load. You may also need to modify the code to account for nulls in any of the three qualifiers.

how to load specific attributes from two table to another?

I am trying to load attributes from two tables to one table.
I have a Location table:
Id City State Country
===============================
1 New York New York USA
2 Portland Oregon USA
3 Tokyo Honshu Japan
And a User table:
Id First_Name Last_Name Hometown_City Hometown_State Hometown_Country
===========================================================================
1 Brett Burr New York New York USA
2 Bucky Beaver Portland Oregon USA
3 Ranma Saotome Tokyo Honshu Japan
I'm creating a new table for users, which instead of containing the separate Hometown fields, has a Hometown_Id foreign key.
Something like:
Id First_Name Last_Name Hometown_Id
========================================
1 Brett Burr 1
2 Bucky Beaver 2
3 Ranma Saotome 3
However, I'm having a problem with the syntax when inserting the data into the new Users table.
I can insert the non-location based fields easily with a command like:
INSERT INTO newusers (Id, First_Name, Last_Name)
SELECT DISTINCT Id, First_Name, Last_Name
FROM users
However, I'm not sure of the correct syntax to then add the values from the location table
Assuming that you have the appropriate constraints, and that the Location table contains unique entries, the following should work:
INSERT INTO newusers (Id, First_Name, Last_Name, Hometown_Id)
SELECT users.Id, users.First_Name, users.Last_Name, locations.Id
FROM users
INNER JOIN locations
ON locations.City = users.Hometown_City
AND locations.State = users.Hometown_State
AND locations.Country = users.Hometown_Country
If you have more than one location needed (such as a 'current residence' entry), alias and join to the locations table (from users) a second time.