Tell Microsoft SQL Server Management to show 2 specific entries - sql

In my database management class assignment, the teacher wants us to create a request that will pull the first and last name of 2 passengers with their id numbers.
The table (PASSAGER) used for that assignment has the following columns:
ID_PASS (the id number of the passengers)
NOM (the last name of the passengers)
PRENOM (the first name of the passengers)
CODE (a unique code created by the airline company to identify each passenger which is a combination of their last name, first name and number of their civic address (the address where the passenger live))
NO_CIVIQUE (the number of their civic address)
RUE (the name of the street where the passenger lives)
LOCALITE (the city/town/municipality where the passenger lives)
REF (a reference number, I asked the teacher what was the specific role of that number but he didn't know what it was for, the only thing we know is that it isn't unique to each passenger and is therefore shared between passengers)
ID_PAYS (the id of the country where the passenger comes from)
NOPASSPT (the passport number of the passenger)
Like I said, we need to pull the last name (NOM) and first name (PRENOM) of 2 specific passengers with their id number (ID_PASS), specifically the ones with the number 344 and 346 so I did something like this:
SELECT NOM, PRENOM
FROM PASSAGER
WHERE ID_PASS = 344 AND 346
The request worked... Sort of, it did showed the columns NOM and PRENOM but they were empty.
My guest on why it didn't worked would be that the condition
WHERE ID_PASS = 344 AND 346
isn't the right syntax or the right way to do it, but I feel I'm on the right track.
I've also tried:
SELECT NOM, PRENOM
FROM PASSAGER
WHERE ID_PASS = 344, 346
But that one just gave me an error and it failed.
So yeah I'm kinda stuck on that one

The problem you are facing is a logic problem. The ID_PASS cannot be both 344 and 346 at the same time, so do not use AND - you want to use OR. The ID_PASS is either 344 or 346. There are two ways to do this - one is to use OR, the other is to use IN (which is just a shortcut or syntactical sugar for OR).
Using OR:
SELECT NOM, PRENOM
FROM PASSAGER
WHERE ID_PASS = 344 OR ID_PASS = 346;
Using IN:
SELECT NOM, PRENOM
FROM PASSAGER
WHERE ID_PASS IN (344, 346);

Related

SQL: Find minimal occurence of a specific value

I have trouble exactly explaining what my problem is. Let me start with what I am NOT asking: I am NOT asking for the minimal value of a column.
Assume the following table, which in one column lists names and in the other column lists guesses estimating the age of the person on the left. Multiple people are guessing so there are different guesses:
Name
AgeGuess
Max
34
Jennifer
21
Jordan
88
Max
29
Jennifer
22
Jordan
22
Jordan
36
...
...
and so on and so on. My question is: What is an SQL command that could give me a table filled by all names who were guessed the LEAST to be for example 36 (must be a specific value !). Additionally I'd like also like to know how often they were guessed 36. If nobody guessed them 36 I'd like to know that too.
In this example only Jordan was guessed to be 36. All the others were never guessed to be 36. I would expect an output like this:
Name
GuessedToBe36Count
Max
0
Jennifer
0
The table above is the result of me asking which people were guessed to be 36 the least amount of times.
My attempt was to group them by how often they were guessed 36. However if they were never rated 36, they also do not appear in the table at all, meaning I cannot just compute the minimum of the column.
If you want to get count of guessed ages by each user, group by user
SELECT name, COUNT(ageGuess) AS total, ageGuess FROM user_guess GROUP BY name, ageGuess ORDER BY name, total ASC
You will get then something similar to this:
name
total
ageGuess
Jordan
1
33
Jordan
3
65
Max
1
34
Please note that it will not return not guessed values. You can fill-in it when processing in back-end.
To have your wanted output, do it with sub-query:
SELECT name, (SELECT COUNT(ageGuess) FROM guesses g2 WHERE g2.name = g1.name AND ageGuess = 36) FROM guesses g1 GROUP BY name
Example

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.

Having trouble with query giving different results inside subform vs just running query

I'm trying to use a query to make a list of records for use in a subform. This will allow a user to pick the record they want to edit. With no changes to the SQL or tables I get different results running the query directly or using the same query as the recordsource of my form.
households has a record for each address - h_id is the ID number
people is a list of people in each household - household_id links to a household
Query SQL
SELECT P.last_name, H.h_id, P.first_name, H.second_last_name, H.address, H.mailing_address, H.phone, H.second_phone FROM households AS H INNER JOIN people AS P ON H.h_id = P.household_id WHERE (((P.last_name) Is Not Null))
the only difference in the form is that I have to put the WHERE part under Filter
if the query is run alone I get
last_name h_id first_name address
Johnson 1289 Mike 26 Aiken Ave
Raty- Johnson 1289 Mary 26 Aiken Ave
when the query is the recordsource for the form I get
last_name h_id first_name address
Raty- Johnson 1289 Mary 26 Aiken Ave
So far I assume that the form is killing the second record for maybe matching h_id, but I have no idea how to stop it. The output from running the query alone is what I want, only in the form. This will allow the form to have other people in the household listed, in case one of them come instead of the person who signed up.

Oracle: LIKE where any part of one string matches any part of another string

I am using PL/SQL v7.1
I am trying to find all address records where the country name has been entered in one of the address line fields, and also the country field.
The problem is that the country details have not been entered consistently eg.
addr4 addr5 country
---------- ---------- ---------------
JERSEY UK(JERSEY)
IRELAND REPUBLIC OFIRELAND
DOUGLAS ISLE OF MAN UK(ISLE OF MAN)  
So, I need to find the records where ANY PART of the Country field is also found in either addr4 or addr5.
I started with this
SELECT *
FROM test_addresses
WHERE addr4||addr5 LIKE '%'||country||'%'
I know this doesn't work because it will, taking the 1st record as an example, check if 'UK(JERESEY)' is found in addr4||addr5 and ,so, no match will be found. But how do I make it check if 'JERSEY' is found in addr4||addr5
Try this way:
SELECT *
FROM test_addresses
WHERE (addr4 is not null and country like '%'||addr4||'%')
or (addr5 is not null and country like '%'||addr5||'%')
Sql Fiddle Demo
I don't know so much about plsql
but I think your query is backwards, try this.
SELECT *
FROM test_addresses
WHERE country LIKE '%'||addr4||'%'
or country LIKE '%'||addr5||'%'

postgis query for addresses (with osm data)

I want to make queries for addresses to postgis database with data from openstreetmap, check if such address exist in database and if so, get coordinates. Database was filled from .pbf file using osmosis. This is schema for the database http://pastebin.com/Yigjt77f. I have addresses in form of city name, street name and number of street. The most important for me is this table:
CREATE TABLE node_tags (
node_id BIGINT NOT NULL,
k text NOT NULL,
v text NOT NULL
);
k column is in form of tags, one that I'm interested are: addr:housenumber, addr:street, addr:city and v is corresponding value. First I'm searching if name of city matches one in database, than in results set I'm searching for street and than for house number. The problem is that I don't know how to make SQL query that will get this result with asking only once. I can ask first only for city name, get all node_id that match my city and save them in java program, than make queries asking for each found(matching my city) id_number (list from my java program) for the street, and so on. This way is really slow, because asking for more detailed information (city than street than number) I have to make more and more queries and what is more I have to check a lot of addresses. Once I have matching node_id I can easily find coordinates, so that's not a problem.
Example of this table:
node_id | k | v <br>
123 | addr:housenumber | 50
123 | addr:street | Kingsway
123 | addr:city | London
123 | (some other stuff) | .....
100 | addr:housenumber | 121
100 | addr:street | Edmund St
100 | addr:city | London
I hope I explained clearly what is my problem.
This is not as easy as you might think. Addresses in OSM are hierarchically, like in the real world. Not all elements in OSM have a full address attached. Some only have addr:housenumber and simply belong to the nearest street. Some have addr:housenumber and addr:street but no addr:city because they simply belong to the nearest city. Or they are enclosed by a boundary relation which specifies the corresponding city. And instead of addr:housenumber there are sometimes also just address interpolations described by the addr:interpolation key. See the addr key wiki page for more information.
The Karlsruhe Schema page in the OSM wiki explains a lot about addresses in OSM. It also mentions associatedStreet relations which are sometimes used to group house numbers and their corresponding streets.
As you can see a single query in the database probably won't suffice. If you need some inspiration you can take a look at OSM's address search engine Nominatim. But note that Nominatim uses a different data base scheme than the usual one in order to optimize address queries. You can also take a look at one of the many routing applications which all have to do address lookups.