MSSQL query where to include city name Abbreviations - sql

Have search on my site and user need to input a city name.
Even though I have an auto complete from my database in city input they can still type any name.
So the db table will have city names such as:
Saint Paul
St. Louis
And user can input "Saint Louis" / "St Louis"
and i still need there to be a result from table even though it is not an exact match.
The same goes for Mt/Mt./Mount and so on.
How can this be achieved?
Thanks

Related

Using LIKE clause when formats are different

I was given a patient list with names and I am trying to match with a list already in our database and am having troubles given the format of the name field in the patient list. This list is taken from a web form so people can input names however they want so it does not match up well.
WEBFORM_NAME
PATIENT_NAME
JOHN SMITH
SMITH,JOHN L
SHANNON BROWN
BROWN,SHANNON MARIE
Is there a way to use a LIKE clause in an instance like this? All I really need is the LIKE clause to find the first name because I have joined on phone number and email address already. My issue is when households have the same phone number and email address (spouses for example) I just want to return the right person in the household.
Not sure if all you need is to get first name, here is the WIldCard expression to get first name
SELECT LEFT(WEBFORM_NAME,CHARINDEX(' ',WEBFORM_NAME)-1) AS FirstName1,
SUBSTRING(PATIENT_NAME,CHARINDEX(',',PATIENT_NAME)+1,(CHARINDEX(' ',PATIENT_NAME)-CHARINDEX(',',PATIENT_NAME))) AS FirstName2
FROM yourTable
The assumption here seems to be that the webform (where user would manually) type in the name would be of the format <First Name> [<optional middle Name(s)>] <Last Name>, where as the data stored in the table are of the form <Last Name>,<First Name> [<optional middle Name(s)>]. Its not an exact science, but since other criteria (like email, phone etc) have been matched best case
select *
from webform w, patient p
where
-- extract just the last name and match that
regexp_like(p.name,
'^' ||
regexp_extract(w.name,
'([^[:space:],][[:space:],])*([^[:space:],]+)', 1, 2))
and -- extract the first name and match it
regexp_like(p.name,
',[[:space:]]*' ||
regexp_extract(w.name, '(^[^[:space:],]+)'))
Since webform is free form user input, its hard to handle abbreviated middle name(s) and other variations so using the above will do first name and last name based matching which in addition to the matching you are already doing should help.

Logic and query for getting first name from full name

I have a large database with a full name field. The full name can be in any format and can also include title. For example, all of the following are possible:
John Smith
Smith, John
Mr. John Smith
Dr. John Smith
Mrs. Jane Smith
Ms. Jane Smith
Jane Smith, Esq.
Jane Smith, MD
I want to preserve the full name field, but also add a predicted first name field from a separate table (that contains name, gender).
I think the proper logic for this is to match the first name values + a space to the full name table via LIKE. The space is so that "David Johnson" doesn't match to "John."
I think the way to accomplish this is an update statement with a subquery in it. Here's what I have so far:
UPDATE "employees"
SET "employees".FirstName = (SELECT firstname
FROM genders
WHERE fullname LIKE '%"employees".FirstName %')
What you really want to do is use Postgres's full text search capabilities. You can create a stopwords list containing titles to exclude (Mr, Ms, etc.). Then, set up a search configuration to use your stopwords.
Once you've set up your search configuration correctly, your query will look something like this (this is the SELECT variant: Changing to UPDATE will be trivial):
SELECT employees.full_name, genders.first_name
FROM employees
LEFT JOIN genders ON
TO_TSVECTOR('english_titles', employees.full_name)
## TO_TSQUERY('english_titles', genders.first_name)
This will give you the following results:
full_name first_name
"John Smith" "John"
"Smith, John" "John"
"Mr. John Smith" "John"
"Dr. John Smith" "John"
"Mrs. Jane Smith" "Jane"
"Ms. Jane Smith" "Jane"
"Jane Smith, Esq." "Jane"
"Jane Smith, MD" "Jane"
"David Johnson" NULL
In order for this to work, you'll need to take the following steps:
Create a stopwords file containing job titles, and put it in your $SHAREDIR/tsearch_data Postgres directory. See https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-STOPWORDS.
Create a dictionary that uses this stopwords list (you can probably use the pg_catalog.simple as your template dictionary). See https://www.postgresql.org/docs/9.1/static/textsearch-dictionaries.html#TEXTSEARCH-SIMPLE-DICTIONARY.
Create a search configuration for job titles. See https://www.postgresql.org/docs/9.1/static/textsearch-configuration.html.
Alter your search configuration to use the dictionary you created in Step 2 (cf. the link above).
Now, with all that said, you need to think carefully about a couple of things:
How do you expect to handle people whose last name matches a first name in your Genders table? For example, you have someone called John Stuart, and both John and Stuart are in your genders table. How do you expect to handle that?
How do you expect to handle people with nicknames, or only have one name? I would strongly encourage you to read Falsehoods Programmers Believe About Names to make sure you're not making any ill-founded assumptions.
Why is your table containing first named called genders? Do you expect to match people to first-name by gender? If so, that's a dangerous road to go down---there are names that can be used for either sex.

Excel 2013 VLOOKUP() based on multiple criteria, retrieving multiple rows

I have an issue that can (I believe) be solved by just excel, and may won't require VBA (I could be wrong). I believe it can be solved by nested functions but the formula I've tried has not worked.
Here's my data:
Name Report # Name
Mark Doe ReportXXX Mark Doe
Connie Doe ReportYYY Connie Doe
Debbie Doe REPORTYYY Debbie Doe
Valerie Doe FSMVALTR1 Valerie Doe
Jeff Doe FSMVALTR1 Jeff Doe
Andy Doe RAZXYBCA1 Andy Doe
Ryan Doe RAZXYBCA1 Ryan Doe
Andy Doe RAZ111111 Jill Doe
Ryan Doe RAZ222112 Amanda Doe
This list goes on for about ~4000 rows in the first NAME and REPORT # columns. In the second NAME column I have ~160 rows.
The second name column identifies all the users who actually use the report, with no duplicates. The two name and report # columns have many duplicates, since users have access to multiple reports, and many of them are the same report used for different purposes. Since the second NAME column has so few rows, the names don't match up all the way through, which can be observed near the bottom of both the NAME columns.
What I need to do is have a VLOOKUP that identifies the name in both of the columns and then returns the report number that each individual has access to across rows (horizontally), not down the columns. It also needs to I.D. numerous reports since individuals have access to anywhere from 1-15 reports, starting at the second and so on after the previous has been extracted.
Ideally it would look something like this:
Name Report # Name ex column ex column ex column
Mark Doe ReportXXX Mark Doe ReportXXX ReportAAA ReportB
I didn't list the other reports "Mark Doe" has access to and these would be somewhere down the long list of ~4000, along with his name repeated multiple times in the first NAME column, but the second "unique" name column would be where it is returning the reports to, across rows.
I made a method that uses additional three columns and it worked for me.
I used the data you provided above.
Add three columns to the left.
in A2 enter =COUNTIFS($D$2:$D2,D2,$E$2:$E2,E2).
in B2 enter =SUMIFS($A$2:$A2,$A$2:$A2,1,$D$2:D2,D2).
in C2 enter =D2&B2.
Now copy those cells to all your 4000 rows.
Now next to the second name column add column headers numbered from 1 to as many reports you think can be the max one user can have (you said 15).
Now enter this vlookup in F2 =IFERROR(VLOOKUP($F2&G$1, your table array starting from column C as absolute/fixed ,3,FALSE),"") in my case it was =IFERROR(VLOOKUP($F2&G$1,$C$2:$E$11,3,FALSE),"").
Copy the formula accross all columns with number headers and down all rows that have names in second name column (160).
your sheet shuld look something like this image
All the best let me know if it worked for you.
Have you explored the option of using a Pivot Table?
The output would look like this:
With the Pivot Table setup like this:
This method would make for a cleaner view, as your current method looks to repeat ~4,000 times (once for each report & name combo). Hopefully this works for what you need.

How do you query only part of the data in the row of a column - Microsoft SQL Server

I have a column called NAME, I have 2000 rows in that column that are filled with people's full names, e.g. ANN SMITH. How do I do a query that will list all the people whose first name is ANN? There are about 20 different names whose first name is ANN but the surname is different.
I tried
and (NAME = 'ANN')
but it returned zero results.
I have to enter the FULL name and (NAME = 'ANN SMITH') ANN SMITH to even get a result .
I just want to list all the people with there first name as ANN
Try in your where clause:
Where Name like 'ANN %'
Should work mate.
ANN% will find all results where ANN is first then anything after.
%ANN% will find the 3 letters ANN in any part of that rows field.
Hope it helps
Also usually Name is separated into First names and second name columns.
this will save Having to use wild cards in your SQL and provide A bit more normalized data.
SELECT NAME
FROM NAMES
WHERE NAME LIKE 'ANN %'
This should wildcard select anything that begins with 'ANN' followed by a space.

SQL Query Data Collect

I have a SQL server table that has a list of Usernames and a list of points ranging from 1 to 10,000.
I want to display the number of points in my VB.NET program from the username given. For example, if I type in "john" in the first box the program will give me a message box saying whatever amount of points "john" has. I'm not really sure about SQL queries so please help me out here.
This is the Table Structure:
Usernames Points
-----------------------------
John 20
Kate 40
Dan 309
Smith 4958
Depending on the structure of the table, a suitable query is one of these:
select sum(points) as points
from usernames
where name='username';
or
select points
from usernames
where name='username';
or
select count(*) as points
from usernames
where name='username';