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 ....)
Related
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.)
I have a table of health plan subscribers we'll call it table1. Members are listed multiple times as all of their benefits are listed (Plan Name field). In some cases they may have an address listed for one Plan Name and not for the other. I'm blanking on how to create an update query that will fill in the Street Address 1, Street Address 2, City, State, and Zip Code based on the same fields that they have listed for another Plan Name in the same table? I can identify the members by their Member_ID
Using most of the comments and suggestions above:
If you link the table to itself:
SELECT Parent.*, table1.PlanName AS Plan FROM table1 AS Parent
LEFT JOIN table1 on Parent.Member_ID = table1.Member_ID
WHERE Parent.zipcode is not null
This should get what you have asked for!
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
i have a table which store user name, hobby and city .hobby field contain different hobby joined using "," operator eg swimming, basket, cricket. I want to search user name who match at least one hobby according to my search criteria.
You should not have multiple attributes in one column. That's one of the number one rules of 3nf database design. Now you have to figure out ways to parse this data. This issue only gets worse and worse each and every day. Seperate the hobbies as multiple rows in your database.
I agree with #JonH that there shouldn't be more than one piece of information in a column. It stops the row being truly atomic.
But you are where you are, and you can use the LIKE clause to return rows that match a substring within a column.
Something like:
select hobbycolumn from hobbytable where hobbycolumn like '%swimming%'
for example
To do this properly you need to restructure your tables if possible. For what you are looking for a possible way would be to have 3 tables. I'm not sure who the city belongs to, so I put it with the user.
1 for user with the following cols:
id
name
city
A table for for hobbies:
id
name
And a user_hobbies join table that allows each user to have multiple hobbies, and each hobby to have multiple users:
id
user_id (foreign key)
hobby_id (foreign key)
Then searching for a user with a certain hobby is:
SELECT user.id, user.name FROM user
INNER JOIN 'user_hobbies' on user_hobbies.user_id=user.id
INNER JOIN 'hobbies' on hobbies.id = user_hobbies.hobby_id
WHERE hobbies.name LIKE "query";
I am trying to setup a contacts database for mailings and I am trying to fully automate the labels but can't figure out how.
Where in the database would I store the name that would appear on the top of a mailing label:
mr & mrs joe thomson
dr. and mrs james berry
Schwartz family
This seems like it would have to be a calculated field based on a number of different pieces of data.
Any suggestions on how you have a mailings database and generate names for labels directly?
Building off the data model I suggested in your previous question, I'll update the CONTACTS table to include:
SALUTATION (Mr, Mrs, Dr, etc)
I would determine to use "Thompson Family" versus Mr. Joe Thompson and Mrs. Terry Thompson and Joe and Billy based on the number of personal contacts = 2+ for the same address, with the same last name.
References:
salutation
A fairly normalized design would look something like:
Location(addr_id,primary_contact_id, street_addr, city, post_code, country)
Contact(contact_id,first_name, last_name, title);
LivesAt(contact_id,addr_id)
MarriedTo(contact_id_1,contact_id_2)
ChildOf(parent_id,child_id)
These would basically be your tables. Then you could create views:
1.Family. Assume a family is at least one parent and a child living at the same address, and they share the same surname (in the case of a parent and child having different surnames, you will address the letter to them both by their full names).
CREATE VIEW Family AS
SELECT UNIQUE last_name, addr_id, street_addr, city, post_code, country FROM
(SELECT p1.contact_id, p1.first_name, p1.last_name FROM Contact AS p1)
INNER JOIN
(SELECT p2.contact_id, p2.first_name, p2.last_name FROM Contact AS p2)
ON (p2.last_name = p1.last_name AND p2.contact_id IN ChildOf
AND p1.contact_id IN ChildOf)
INNER JOIN
Location AS l
ON (p1.contact_id = l.primary_contact_id)
OR (p2.contact_id = l.primary_contact_id)
Format as you see fit.
2.Married couples with no children.
CREATE VIEW Couple AS
SELECT * FROM
(SELECT C.contact_id, C.last_name, C.title FROM Contact AS C
INNER JOIN MarriedTo AS M
ON (M.contact_id_1=C.contact_id)
INNER JOIN
SELECT D.contact_id, D.last_name, D.title FROM Contact as D
ON (M.contact_id_2=D.contact_id)
INNER JOIN Location AS L
ON
L.addr_id NOT IN Family
AND (L.primary_contact_id = M.contact_id_1)
OR (L.primary_contact_id = M.contact_id_2)
And so on.
I personally don't like encoding these kind valid values in the database column definition. You'd have a large administration overhead. Managing these values in a distinct table is better, but having a foreign key into another table you to read the label just didn't seem right to me. Last time I needed to do something similar I added the column for the label as a simple varchar column.
But what do you do to avoid duplicates and very similar labels (e.g. "Mr" and "Mr.")? I added an index on the column and added an AJAX query in the frontend to list all distinct labels available and perfom an autocompletion. This works really awesome because
the user is not forced to scroll through a long list of possible values
you don't need to administrate the values yourself
This way you'd allow any label including "Mr. and Mrs." or "Prof. Dr. Dr.".
Given your clarifications - I would create an additional table.
I'm assuming you have a "contacts" table which contains a distinct list of people.
You could also have a "household" table which contains a list of last names or households. I would put the address in THIS table.
Then, the each contact person would have a field linking them to a household (even if there is only one person per household.)
Each contact person would also have a field for "primary contact" containing a 1/0 value.
Then, you could have query logic something like the following:
if count(*) of contacts per household = 1 then
label = contact.title & contact.nameinfo
if count(*) of contact per household = 2 and both of those contacts are primary contacts then
label = primarycontact.title & name plus primarycontact2.title & name
else
label = household.lastname & "family"
You'll want to play with the logic to get it perfect, but the real key is having a household table with a separate address and a contact table with the people within that address.