SQL join tables with wildcard (MS Access) - sql

how do i join following tables with wildcards? I would like to get all distinct rows from People table which contains SearchedName from SearchedPeople table.
SearchedPeople:
SearchedName
--------
Andrew
John
John Smith
People:
ID PersonName Attribute Age
----------------------------------------
1 John Smith 1 23
2 John Smith Jr 3 25
3 John Smith Jr II 4 73
4 Kevin 2 21
5 Andrew Smith 1 14
6 Marco 5 90
Desired Output:
PersonName Attribute Age
----------------------------------------
John Smith 1 23
John Smith Jr 3 25
John Smith Jr II 4 73
Andrew Smith 1 14
Code i got so far which doesnt wor. It returns three empty rows(why is that?).
SELECT b.PersonName, b.Attribute, b.Age
FROM SearchedPeople a
LEFT JOIN People b ON "%"&a.SearchedName&"%" like b.PersonName

It returns three empty rows because you don't have any columns from table a (SearchedPeople) and the LEFT JOIN didn't produce a match.
The reason is your criteria is in the wrong order you are searching for PersonName in the string %Searchedname% you need to switch that around. Also Access doesn't like the % as much as it likes the asteriks * for wilcard unless you make some changes to the query or configuration of MS-Access see below comment from Parafait.
I just tested this:
SELECT a.SearchedName
,b.PersonName, b.Attribute, b.Age
FROM
SearchedPeople a
LEFT JOIN People b
ON b.PersonName LIKE ("*" & a.SearchedName & "*")
Edit:
Good Ms Access specific information from a comment from #Parafait pasting in answer in case comment every got deleted.:
Use ALIKE and percents work. And if OP connects to MS Access via OLEDB and not the GUI .exe program, the % operator is required for LIKE statements in coded SQL. OP can also change database settings to ANSI-92 mode to always use % wildcards.

Related

Loop through a table based on multiple conditions

Students table
student_id student_name
1 John
2 Mary
Grades table
student_id year grade_level school Course Mark
1 2015 10 Smith High Algebra 95
1 2015 10 Smith High English 96
1 2016 11 Smith High Geometry 85
1 2016 11 Smith High Science 88
2 2015 10 Smith High Algebra 98
2 2015 10 Smith High English 93
2 2016 11 Smith High Geometry 97
2 2016 11 Smith High Science 86
I'm trying to show results for each year and what class a student took with the grade.
So the final output i'm looking for is something like:
[student_id1] [year1] [grade1] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
[student_id1] [year2] [grade2] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
[student_id2] [year1] [grade1] [school1]
[course1] [mark1]
[course2] [mark2]
[course3] [mark3]...
This would all go in one column/row. So in this particular example, this would be my result:
1 2015 10 Smith High
Algebra 95
English 96
1 2016 11 Smith High
Geometry 85
Science 88
2 2015 10 Smith High
Algebra 98
English 93
2 2016 11 Smith High
Geometry 97
Science 86
So anytime a student id, year, grade, or school name changes, I would have a line for that and loop through the classes taken within that group. And all of this would be in one column/row.
This is what I have so far but I'm not sure how I can properly loop through course and grades for each group. I'd appreciate it if I can be pointed in the right direction.
select s.student_id + '' + year + '' + grade_level + '' + school
from students
join grades on students.student_id = grades.student_id
If you want to do it in your SQL Enviromnment, it depends on the Database Management System you are using.
For example, if you are using Transact SQL you can try to look at this link.
Generally this kind of loops and interactions are done in the programming language that is coupled with the SQL DB.
Anyway, you should look at Stored Procedures and Cursors if you really want to do this in SQL.
You are trying to mix presentation with retrieval of data from database tables. Looping through the resultset in sql can be achieved via cursor but that isn't adviced. You are better off by pulling the required data using two queries and later print it using a language of your choice.

appropriate method for text match in one column to other column in oracle

I have to write a query in Oracle. I have a table called 'Entity' with 2 columns 'Pref_mail_name' and 'spouse_name'.
Now i want list of all spouse_name where the last name of the spouse_name is not populated from pref_mail_name.
For example my table has following data
Pref_mail_name spouse_name
Kunio Tanaka | Lorraine
Mrs. Betty H. Williams | Chester Williams
Mr. John Baranger | Mrs. Cathy Baranger
William kane Gallio | Karen F. Gallio
Sangon Kim | Jungja
i need output as 1st and 5th row only. I did some analysis and came up with oracle built in function
SELECT PREF_MAIL_NAME, SPOUSE_NAME, UTL_MATCH.JARO_WINKLER_SIMILARITY(a, b)
similarity from entity
order by similarity;
But above query is not looking genuine.Even though spouse last name is not populated from pref_mail_name its giving a value above 80 for similarity.

VBA/SQL recordsets

The project I'm asking about is for sending an email to teachers asking what books they're using for the classes they're teaching next semester, so that the books can be ordered. I have a query that compares the course number of this upcoming semester's classes to the course numbers of historical textbook orders, pulling out only those classes that are being taught this semester. That's where I get lost.
I have a table that contains the following:
Professor
Course Number
Year
Book Title
The data looks like this:
professor year course number title
--------- ---- ------------- -------------------
smith 13 1111 Pride and Prejudice
smith 13 1111 The Fountainhead
smith 13 1222 The Alchemist
smith 12 1111 Pride and Prejudice
smith 11 1222 Infinite Jest
smith 10 1333 The Bible
smith 13 1333 The Bible
smith 12 1222 The Alchemist
smith 10 1111 Moby Dick
johnson 12 1222 The Tipping Point
johnson 11 1333 Anna Kerenina
johnson 10 1333 Everything is Illuminated
johnson 12 1222 The Savage Detectives
johnson 11 1333 In Search of Lost Time
johnson 10 1333 Great Expectations
johnson 9 1222 Proust on the Shore
Here's what I need the code to do "on paper":
Group the records by professor. Determine every unique course number in that group, and group records by course number. For each unique course number, determine the highest year associated. Then spit out every record with that professor+course number+year combination.
With the sample data, the results would be:
professor year course number title
--------- ---- ------------- -------------------
smith 13 1111 Pride and Prejudice
smith 13 1111 The Fountainhead
smith 13 1222 The Alchemist
smith 13 1333 The Bible
johnson 12 1222 The Tipping Point
johnson 11 1333 Anna Kerenina
johnson 12 1222 The Savage Detectives
johnson 11 1333 In Search of Lost Time
I'm thinking I should make a record set for each teacher, and within that, another record set for each course number. Within the course number record set, I need the system to determine what the highest year number is - maybe store that in a variable? Then pull out every associated record so that if the teacher ordered 3 books the last time they taught that class (whether it was in 2013 or 2012 and so on) all three books display. I'm not sure I'm thinking of record sets in the right way, though.
My SQL so far is basic and clearly doesn't work:
SELECT [All].Professor, [All].Course, Max([All].Year)
FROM [All]
GROUP BY [All].Professor, [All].Course;
Use your query as a subquery and INNER JOIN it back to the [ALL] table to filter the rows.
SELECT
a.Professor,
a.Year,
a.Course,
a.title
FROM
[ALL] AS a
INNER JOIN
(
SELECT [All].Professor, [All].Course, Max([All].Year) AS MaxOfYear
FROM [All]
GROUP BY [All].Professor, [All].Course
) AS sub
ON
a.Professor = sub.Professor
AND a.Course = sub.Course
AND a.Year = sub.MaxOfYear;

Choosing criteria in Access

I have two excel files that I linked together to make a Query in Access.
Table One Table Two
Name ID Name ID
John 342 John 342
Mike 234 Mike 234
Mich 980 Mich 980
Jenn 098 Quay 309
Anna 145 Pond 612
Lope 546
Anna 145
How do i set the criteria in the access query so that they match the ID and only show me the names on the left matching the right. Anything from table two that doesn't match with table one to disregard?
If I have the following query:
Name Name
Table one Table two
I get the following result:
John John
Mike John
Mich John
Jenn John
Anna John
John Mike
Mike Mike
Mich Mike
Jenn Mike
Anna Mike
and so forth... So i am figuring i have to set a criteria... which is where i am stuck at... any help would be appreciative.
You can use an INNER JOIN:
SELECT [Table 1].Name, [Table 2].Name
FROM [Table 1]
INNER JOIN [Table 2]
ON [Table 1].Name = [Table 2].Name
You can create this query in MS Access by adding both tables to the query design window and then dragging the field you want to match from one table to the next or by switching to SQL view and typing or pasting SQL.
More information:
Fundamental Microsoft Jet SQL for Access 2000
Intermediate Microsoft Jet SQL for Access 2000
Advanced Microsoft Jet SQL for Access 2000

How To Traverse a Tree/Work With Hierarchical data in SQL Code

Say I have an employee table, with a record for each employee in my company, and a column for supervisor (as seen below). I would like to prepare a report, which lists the names and title for each step in a supervision line. eg for dick robbins, 1d #15, i'd like a list of each supervisor in his "chain of command," all the way to the president, big cheese. I'd like to avoid using cursors, but if that's the only way to do this then that's ok.
id fname lname title supervisorid
1 big cheese president 1
2 jim william vice president 1
3 sally carr vice president 1
4 ryan allan senior manager 2
5 mike miller manager 4
6 bill bryan manager 4
7 cathy maddy foreman 5
8 sean johnson senior mechanic 7
9 andrew koll senior mechanic 7
10 sarah ryans mechanic 8
11 dana bond mechanic 9
12 chris mcall technician 10
13 hannah ryans technician 10
14 matthew miller technician 11
15 dick robbins technician 11
The real data probably won't be more than 10 levels deep...but I'd rather not just do 10 outside joins...I was hoping there was something better than that, and less involved than cursors.
Thanks for any help.
This is basically a port of the accepted answer on my question that I linked to in the OP comments.
you can use common-table expressions
WITH Family As
(
SELECT e.id, e.supervisorid, 0 as Depth
FROM Employee e
WHERE id = #SupervisorID
UNION All
SELECT e2.ID, e2.supervisorid, Depth + 1
FROM Employee e2
JOIN Family
On Family.id = e2.supervisorid
)
SELECT*
FROM Family
For more:
Recursive Queries Using Common Table Expressions
You might be interested in the "Materialized Path" solution, which does slightly de-normalize the table but can be used on any type of SQL database and prevents you from having to do recursive queries. In fact, it can even be used on no-SQL databases.
You just need to add a column which holds the entire ancestry of the object. For example, the table below includes a column named tree_path:
+----+-----------+----------+----------+
| id | value | parent | tree_path|
+----+-----------+----------+----------+
| 1 | Some Text | 0 | |
| 2 | Some Text | 0 | |
| 3 | Some Text | 2 | -2-|
| 4 | Some Text | 2 | -2-|
| 5 | Some Text | 3 | -2-3-|
| 6 | Some Text | 3 | -2-3-|
| 7 | Some Text | 1 | -1-|
+----+-----------+----------+----------+
Selecting all the descendants of the record with id=2 looks like this:
SELECT * FROM comment_table WHERE tree_path LIKE '-2-%' ORDER BY tree_path ASC
To build a tree, you can sort by tree_path to get an array that's fairly easy to convert to a tree.
You can also index tree_path and the index can be used when the wildcard is not at the beginning.
For example, tree_path LIKE '-2-%' can use the index, but tree_path LIKE '%-2-' cannot.
Some recursive function which either return the supervisor (if any) or null. Could be a SP which invokes itself as well, and using UNION.
SQL is a language for performing set operations and recursion is not one of them. Further, many database systems have limitations on recursion using stored procedures as a safety measure to prevent rogue code from running away with precious server resources.
So, when working with SQL always think 'flat', not 'hierarchical'. So I would highly recommend the 'tree_path' method that has been suggested. I have used the same approach and it works wonderfully and crucially, very robustly.