Sql-server: update all rows columns based on IP - sql

I have a table LogPixelCall(example of two rows):
1 d5104006-8a82-4dfe-b6ca-587d25e869e9 1 2 2016-03-07 16:31:41.997 **92.26.242.166** NULL
2 5a5ffea2-3a70-4138-aeb7-4dd94900ef27 1 2 2016-03-07 17:39:57.557 **185.28.19.174** NULL
where bolded is IP, and last NULL field is CountryId from other table.
Now I have Iplookup table, where I have to pass converted IP to long(so I have to use that conversion algorithm) and it returns me CountryCode (GB, US, AU), then I compare CountryCode with Country table, where I store countries. I want to then update LogPixelCall information table manually with CountryId, because this was missing before.
Question: Based on provided database schema, how do I update LogPixelCall CountryId NULL field, if I know ClientIp in LogPixelCall, and I can use IpLookup to get CountryIsoCode and connect with Country?

update LogPixelCall set CountryId = c.Id
--select * /*Check first to make sure */
from LogPixelCall lpc
inner join IpLookup ip on lpc.ClientIp between ip.From and ip.To
inner join Country c on c.Code = ip.CountryIsoCode

Related

SQL to find record with a value in one table but not another table

I have two tables: Address and Address_Backup. Each table can contain multiple rows of data for a single individual because there are multiple address types stored in this table. So the data looks something like this:
ID Code Description Description2 City State
6798 HOME 478 Elm NULL Boise ID
6798 OTHER 405 S Main NULL NULL NULL
Address_Backup is supposed to be identical to Address, but we've found some data that exists in Address_Backup that doesn't exist in Address. I need a query that joins the ID numbers in the two tables and returns data for addresses where the "Other" code type exists in the Address_Backup table but does not exist in the Address table.
Assuming your IDs do not change in either table so that ID 100 in Address always points to ID 100 in Address_Backup:
SELECT *
FROM Address_Backup
WHERE ID NOT IN (SELECT ID FROM Address) AND Code = 'OTHER'
using NOT EXISTS
SELECT *
FROM Address_Backup AS B
WHERE NOT EXISTS (SELECT 1 FROM Address WHERE ID = B.ID) AND Code = 'OTHER'

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

Referring to a column alias in two tables

I have two hive SQL tables which consist of following columns.
table_1
|customer_id | ip_address|
region_table
|country_name | region_name|
I tried,
SELECT table_1.customer_id, table_1.ip_address, getCountry(ip_address) AS Country, region_table.region_name FROM table_1 JOIN region_table ON region_table.country_name = Country;
getCountry() is UDF which returns the country name when the IP address
is passed into it. I want to use that country name to create another
column with the corresponding region from the region_table. And i want
to get the following table as my output.
customer_id | ip_address | Country | region_name
Any thoughts on what I'm missing in my query?
select c.customer_id
,c.ip_address
,getCountry(c.ip_address) as Country
,r.region_name
from table_1 c
join region_table r
on r.country_name =
getCountry(c.ip_address)
In case of Oracle, you can not refer column alias defined in SELECT statement in WHERE clause of same query!! Because database engine first evaluates WHERE clause and identifies eligible rows and then proceeds to fetch columns as defined in SELECT part of query.
In your case, right query should be
select
table_1.customer_id,
table_1.ip_address,
getCountry(ip_address) AS Country,
region_table.region_name
FROM table_1
JOIN region_table ON region_table.country_name = getCountry(table_1 .ip_address);

Join on two dis-similar column

I need to join one column of a table to a column of another table.
Now these two column consists the geographic region data. But the issue is the column dont have exactly same strings od data.
For ex. Latin America in one column and LATM in another.
The data is table if had been same string would be the simplest joins but these two mean the same but then are different strings . What do I use to accomplish my task.
I need to do is
Select * from Table1 Inner Join Table2 on table1.region = table2.region
You would need to create a mapping table which maps every possible region in Table1.region to every possible region in Table2
for example your Mapping table be like.
MappingTable
--------------------------
Region1 | Region 2
--------------------------
Latin America | LATM
Europe | EUR
.....
The you can create a join like
Select *
from
Table1
inner join
MappingTable
on
Table1.region = MappingTable.Region1
inner join
Table2
on
MappingTable.Region2 = Table2.region
You need to make another table which contains information of TWO table Joining like 'Latin America' = 'LATM' and then have to use this table in join.

Compare values from another table that have no common key for a join clause

I have two tables (SQL). One contains an IP address (table a), and the other contains two fields that represent the start an end of an IP range (table b - range_from and range_to). Neither one of these tables contain a common key to perform a join. I need to pull the country code from table b based on the ip address contained in table a; based on that ip address being in the range_from and range_to in table b. So, in other words I need to look to see which range (table B range) that IP from table a is in and pull the country code that corresponds.
I have tried a few things but no luck. Any suggestions/ideas on how this can be accomplished?
table a
ip address name order# address country
255.65.28.214
Carlyle 7458214 45 N. East street United States
table b
range_from range_to country_code
192.168.52.69 192.168.75.11 US
192.0.78.23 192.0.78.99 CN
Here is the formal method:
select a.*, b.country_code
from tablea a join
tableb b
on a.ipaddress between b.range_from and range_to;
If you care about performance there are more efficient ways. The most efficient is to create an index on tableb(range_from, range_to, country_code). Then if you assume there are no overlaps (because there aren't any) and there all your ip addresses in the first table match, then try:
select a.*,
(select country_code
from tableb b
where b.range_from < a.ipaddress
order by b.range_from desc
limit 1
) as country_code
from tablea a;
Note that this uses limit to get one row. That depends on the database and might be top or fetch first 1 rows only or something else.