Choose one significant record from related table - sql

I have a table with customers, and a table with cities.
In the customers table, the city_id is related to the id_city of the cities table.
Other fields in the tables
customers: name, surname
cities: ext_code, description, address_code
The problem is that I have thousands of customers records related to cities in which the ext_code is not present.
The cities table, elsewhere, contains a lot of duplicated records; in the duplicated sets only one record has a valid ext_code.
The problem is: substitute the city_id with a id_city that contains a valid ext_code. The only fields to evaluate to group cities are address_code or description.
Any suggestion?

If the
only fields to evaluate to group cities are address_code or
description
then that's what you should use to join your data on while filtering out the non "valid ext_code" that you mentioned.

Here is a crude way to do a one time update of customer.
You will need to tweak the code to make it work with your system, but that should be easy enough.
UPDATE Customer
SET CityID =
(
--This bit will find cities that look like the one we already have,
SELECT TOP 1 CityID
FROM City AS X
WHERE X.AddressCode = City.AddressCode
OR X.Description = City.Description
ORDER BY X.ExtCode DESC --This puts nulls last!
)
FROM Customer
INNER JOIN City ON City.CityID = Customer.CityID

Related

SQL Query to return a table of specific matching values based on a criteria

I have 3 tables in PostgreSQL database:
person (id, first_name, last_name, age)
interest (id, title, person_id REFERENCES person)
location (id, city, state text NOT NULL, country, person_id REFERENCES person)
city can be null, but state and country cannot.
A person can have many interests but only one location. My challenge is to return a table of people who share the same interest and location.
All ID's are serialized and thus created automatically.
Let's say I have 4 people living in "TX", they each have two interests a piece, BUT only person 1 and 3 share a similar interest, lets say "Guns" (cause its Texas after all). I need to select all people from person table where the person's interest title (because the id is auto generated, two Guns interest would result in two different ID keys) equals that of another persons interest title AND the city or state is also equal.
I was looking at the answer to this question here Select Rows with matching columns from SQL Server and I feel like the logic is sort of similar to my question, the difference is he has two tables, to join together where I have three.
return a table of people who share the same interest and location.
I'll interpret this as "all rows from table person where another rows exists that shares at least one matching row in interest and a matching row in location. No particular order."
A simple solution with a window function in a subquery:
SELECT p.*
FROM (
SELECT person_id AS id, i.title, l.city, l.state, l.country
, count(*) OVER (PARTITION BY i.title, l.city, l.state, l.country) AS ct
FROM interest i
JOIN location l USING (person_id)
) x
JOIN person p USING (id)
WHERE x.ct > 1;
This treats NULL values as "equal". (You did not specify clearly.)
Depending on undisclosed cardinalities, there may be faster query styles. (Like reducing to duplicative interests and / or locations first.)
Asides 1:
It's almost always better to have a column birthday (or year_of_birth) than age, which starts to bit-rot immediately.
Asides 2:
A person can have [...] only one location.
You might at least add a UNIQUE constraint on location.person_id to enforce that. (If you cannot make it the PK or just append location columns to the person table.)

SQL statement for many-to-many WHERE Item IN ALL results, not just one

Put into a simplified way, I have three tables: Products, ProductsCounties, and Counties. We can only sell certain products in certain counties, so there is a many-to-many relationship between Products and Counties with ProductsCounties.
To make it even simpler to ask (because I'm using split strings from a comma separated list in a stored procedure... among magic), let's say I just have a table called WantedCounties with CountyName's County1, County2, and County3 as records. This is basically the result of the split string function based on what I give it. My problem is, I want to give three counties (think WantedCounties is going to be what I'm giving) and that Product has to be available in ALL THREE and not just one, hence why my IN statement fails here.
SELECT DISTINCT p.* FROM Products p
JOIN ProductsCounties pc ON pc.ProductId = p.ProductId
JOIN Counties c ON pc.CountyId = c.CountyId
WHERE c.CountyName IN (SELECT CountyName FROM WantedCounties)
This is as much as I can narrow down my problem for sake of making it easy to ask. Does anyone know how to do this? I want only products that have a relationship with every single county given, not just one match IN the subquery.
I think my issue is I can't grasp how to deal with there being multiple rows being selected because of each county match on the join.
I have also tried something along the lines of = ALL (SELECT CountyName FROM WantedCounties) to no avail.
Edit: I found the solution here. I had to include this:
GROUP BY --All my refrences
HAVING COUNT(DISTINCT c.CountyName) = (
SELECT CountyName
FROM WantedCounties)
)
This only returns products that have a match in every County in WantedCounties. So there had to be all 3 counties in my results to match the 3 counties in WantedCounties in order for it to say "that's all of them."
I found the solution here. I had to include this:
GROUP BY --All my refrences
HAVING COUNT(DISTINCT c.CountyName) = (
SELECT CountyName
FROM WantedCounties)
)
This only returns products that have a match in every County in WantedCounties. So there had to be all 3 counties in my results to match the 3 counties in WantedCounties in order for it to say "that's all of them."

Extract info from one table based on data from antoher

I am kind of new to SQL and I made a couple of tables to practice. The columns may have some unrelated categories but I don't know what else write...
Anyway, basically what i want to do is get info from two tables based on the first and last name from one table.
Here are my tables:
Order
Host
I want create a query to pull the ticket number, height, order, subtotal and total by first and last name. The only orders I want to pull are from John Smith And Sam Ting. So in the end, I want my extraction to have the following columns:
Ticket Number
First Name
Last Name
Height
Order
Subtotal
Total
Any help or direction would be awesome!
With the assumption the tables both have unique Ticket_Numbers and that will provide a one-to-one mapping between then.
SELECT
Order.Ticket_Number,
First_Name,
Last_Name,
Height,
Order,
Subtotal,
Total
FROM Order
JOIN Host on Host.Ticket_Number = Order.Ticket_Number
WHERE
(First_Name = 'John' AND Last_Name = 'Smith')
OR (First_Name = 'Sam' AND Last_Name = 'Ting')
You need to "call" the table name first, and then the column. After that you need to use the "join" for the 2 tables. And finally you need the "where". I didn't look for the details so you need to check the "names".
SELECT Order.Ticket_Number, Order.First_Name, Order.Last_Name, Order.Height, Order.Order, Cost.Subtotal, Cost.Total
FROM Order
INNER JOIN Cost
where First_Name="Jhon" and Last_Name="blablabla"
or
First_Name="SecondGuy" and Last_Name="blablabla"

MS Access query count and show

I have a table with cities and publishers in those cities.
How do I create a query that counts how many publishers are in which city, and then also shows the names of those publishers only for the city with the most publishers.
See if this works for you.
SELECT Sub2.City,
Table1.Publisher
FROM (
SELECT TOP 1 Sub.City, Sub.CountOfPublisher AS MaxOfCountOfPublisher
FROM (SELECT Table1.City,
Count(Table1.Publisher) AS CountOfPublisher
FROM Table1
GROUP BY Table1.City
) AS Sub
ORDER BY Sub.CountOfPublisher DESC
) AS Sub2
INNER JOIN Table1
ON Sub2.City = Table1.City
Note: Replace Table1 with your table name.
Explanation
So, we needed to roll up our aggregation so Access can use the information we provided in our Count.
From the inside out:
We need a Count of Publishers for each City, and we want to Group By each City. This gives us some numbers we can work with per City.
The next piece, we want to select the TOP 1 record from those results, sorted by the Count of Publishers DESC (descending - highest to lowest). So, sorting by the Count Descending makes the first record the City with the highest count of Publishers. We then use that in our final step.
Finally, we wanted the City and the Publishers for the City with the most publishers. Well, thus far we have the City with the most Publishers, but we don't have a list of Publishers. To get those, we need to join our original Table on City.
This basically says, I have the City with the most Publishers, now give me all of the records from our Table where the City is equal to the City (INNER JOIN Table1 ON Sub2.City = Table1.City) we are supplying in our query.

Finding Values From Result of SQL Query in Different Table

I have multiple tables each connected by PersonID.
PhoneNumber contains columns for phone number type (work, cell, home), phone numbers, a value for whether SMS messaging is enabled, and person IDs.
Person contains names and email addresses and its key is person ID
AttributeValue contains the values for a number of 'custom' attributes (each attribute has a unique 'AttributeId'). The key columns in this table are AttributeId, Value, and EntityId. EntityId matches Person Id
I'm trying to find the corresponding names and email addresses from the PersonTable for the Person ID that meets the following criteria.
FROM [rock].[dbo].[AttributeValue]
WHERE AttributeId='1770';
FROM [rock].[dbo].[PhoneNumber]
WHERE IsMessagingEnabled=0 AND NumberTypeValueId=12
First of all in SQL when you got multiple tables related by one ID you can use joins.
For example I got a table Customer(ID,Name,Firstname) , a table Address(ID, CustomerID, Name, PostalCode, City) and a table Phone(ID,CustomerID,PhoneHome,PhoneMobile)
You can use this kind of query to find addresses and phones corresponding to customers :
SELECT [Address.Name], [Phone.PhoneHome], [Phone.PhoneMobile] FROM Address, Phone
INNER JOIN Address ON [Customer.ID] = [Address.CustomerID]
INNER JOIN Phone ON [Customer.ID] = [Phone.CustomerID]
WHERE [Customer.ID] = "Value"
Hope it will help you, at least you can find good examples of joints on :
http://openclassrooms.com/courses/introduction-aux-jointures-sql (I believe you're french so this is a good french site to learn about it.)
Have a good day
Something like this?
SELECT * FROM Person WHERE PersonID IN (SELECT PersonID FROM ....)