Updating table where LIKE has several criteria - sql

I have two tables in PostgreSQL (version 9.3). The first holds id, title and the second holds schdname. I'm trying to create a select statement that will retrieve id and title where the title contains the schdname from the other table. The id, title table can hold several thousand rows. I can do this fine if I use WHERE LIKE for an individual schdname example but there are 40 plus names so this is not practical.
My original query ran like this which I know doesn't work but would show what I'm trying to achieve.
SELECT
id,
title,
dname
FROM
mytable
WHERE
title LIKE (
SELECT
schdname
FROM
schedule
)
This produces an error of more than one row returned by the subquery used as an expresssion. So my question is can this be achieved another way?

Here is one way to do that:
SELECT id, title, dname FROM mutable
JOIN schedule ON mutable.title like '%' || schedule.schdname || '%'
Or a sligtly more readable way:
SELECT id, title, dname FROM mutable
JOIN schedule ON POSITION(schedule.schdname in mutable.title)<>0

Are you actually using a wildcard with like? You don't say so above. If not you can replace like with IN. If you do want to do a wildcard join I'd recommend taking a substring of the columns and comparing that e.g.
names
james
jack
janice
select substr(names,1,2) as names_abbr
from names_table where names_abbr = (select ...)

Related

I want to merge the duplicate names in my table or at least see the names that are unique and look alike

I have a employee table with schema as follows:
Id Name Birthday DeathDay Startdate EndDate
The problem is that I have data as follows:
Bergh Celestin 06/09/1791 14/12/1861
Bergh Célestin 06/09/1791 14/12/1861
Bergh Francois 04/04/1958 11/12/2001
Bergh Jozef Francois 04/04/1958 11/12/2001
Now i want to merge these records as 1 as they are the same person how can i do that?
Also, if I just want to display the list of only those person from the table whose names are possibly same, like above, how can I do that?
I used:
select Distinct name,birthday,deathday from table
but that is not good enough.
I would use a function (.NET or SQL) of sorts to remove the accents as per https://stackoverflow.com/a/12715102/1662973 and then group on that together with the dates. You will need to group on something, as essentially "Bergh Célestin" could actually be a different person to "Bergh Celestin".
Sample:
select
RemoveExtraChars(name)
,birthday
,deathday
from
TABLE
group by
RemoveExtraChars(name)
,birthday
,deathday
For your second Question you can use SQL LIKE Operator:
SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern;

SQL using where contains to return rows based on the content of another table

I need some help:
I have a table called Countries, which has a column named Town and a column named Country.
Then I have table named Stores, which has several columns (it is a very badly set up table) but the ones that are important are the columns named Address1 and Address2.
I want to return all of the rows in Stores where Address1 and Address2 contains the towns in the Countries table.
I have a feeling this is a simple solution but I just can't see it.
It would help if maybe you could use WHERE CONTAINS but in your parameters search in another table's column?
e.g.
SELECT *
FROM Stores
WHERE CONTAINS (Address1, 'Select Towns from Countries')
but obviously that is not possible, is there a simple solution for this?
You're close
SELECT * FROM Stores s
WHERE EXISTS (
SELECT * FROM Countries
WHERE CONTAINS(s.Address1, Town) OR CONTAINS(s.Address2, Town)
)
This would be my first attempt:
select * from stores s
where
exists
(
select 1 from countries c
where s.Address1 + s.Address2 like '%'+c.Town+'%'
)
Edit: Ooops just saw that you want the 'CONTAINS' clause. Then take Paul's solution

Selecting distinct rows based on values from left table

Using Postgres. Here's my scenario:
I have three different tables. One is a title table. The second is a genre table. The third table is used to join the two. When I designed the database, I expected that each title would have one top level genre. After filling it with data, I discovered that there were titles that had two, sometimes, three top level genres.
I wrote a query that retrieves titles and their top level genres. This obviously requires that I join the two tables. For those that only have one top level genre, there is one record. For those that have more, there are multiple records.
I realize I'll probably have to write a custom function of some kind that will handle this for me, but I thought I'd ask if it's possible to do this without doing so just to make sure I'm not missing anything.
Is it possible to write a query that will allow me to select all of the distinct titles regardless of the number of genres that it has, but also include the genre? Or even better, a query that would give me a comma delimited string of genres when there are multiples?
Thanks in advance!
Sounds like a job for array_agg to me. With tables like this:
create table t (id int not null, title varchar not null);
create table g (id int not null, name varchar not null);
create table tg (t int not null, g int not null);
You could do something like this:
SELECT t.title, array_agg(g.name)
FROM t, tg, g
WHERE t.id = tg.t
AND tg.g = g.id
GROUP BY t.title, t.id
to get:
title | array_agg
-------+-----------------------
one | {g-one,g-two,g-three}
three | {g-three}
two | {g-two}
Then just unpack the arrays as needed. If for some reason you really want a comma delimited string instead of an array, then string_agg is your friend:
SELECT t.title, string_agg(g.name, ',')
FROM t, tg, g
WHERE t.id = tg.t
AND tg.g = g.id
GROUP BY t.title, t.id
and you'll get something like this:
title | string_agg
-------+---------------------
one | g-one,g-two,g-three
three | g-three
two | g-two
I'd go with the array approach so that you wouldn't have to worry about reserving a character for the delimiter or having to escape (and then unescape) the delimiter while aggregating.
Have a look at this thread which might answer your question.

MySQL SELECT query string matching

Normally, when querying a database with SELECT, its common to want to find the records that match a given search string.
For example:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
That query should give me all records where 'Bob Smith' appears anywhere in the name field.
What I'd like to do is the opposite.
Instead of finding all the records that have 'Bob Smith' in the name field, I want to find all the records where the name field is in 'Robert Bob Smith III, PhD.', a string argument to the query.
Just turn the LIKE around
SELECT * FROM customers
WHERE 'Robert Bob Smith III, PhD.' LIKE CONCAT('%',name,'%')
You can use regular expressions like this:
SELECT * FROM pet WHERE name REGEXP 'Bob|Smith';
Incorrect:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
Instead:
select count(*)
from rearp.customers c
where c.name LIKE '%Bob smith.8%';
select count will just query (totals)
C will link the db.table to the names row you need this to index
LIKE should be obvs
8 will call all references in DB 8 or less (not really needed but i like neatness)

How to fetch values with a MySQL query?

I want to fetch all the records of First_Name, LastName, First Name Last Name in a mysql Query.
For example,
mytable looks like this:
rec Id First Name Last Name
1 Gnaniyar Zubair
2 Frankyn Albert
3 John Mathew
4 Suhail Ahmed
Output should be like this:
Gnaniyar Zubair, Frankyn Albert, John Mathew, Suhail Ahmed
Give me the SQL.
If this must the done in the query, you can use GROUP_CONCAT, but unless you're grouping by something it's a pretty silly query and the concatenation should really be done on the client.
SELECT GROUP_CONCAT(FirstName + ' ' + LastName
ORDER BY FirstName, LastName
SEPARATOR ', ') AS Names
FROM People;
It is not a matter of getting one row with all the records, but a matter of representation of data. Therefore, I suggest to take a simple SELECT query, take the records you need, then arrange them in the view layer as you like.
On the other hand, why do you need to solve this record concatenation at SQL level and not on view level?
If you wanted to get them in just one row, you're probably not using your database properly.
If you just want to join together the first and last names, that's easy:
SELECT CONCAT(`First Name`, ' ', `Last Name`) FROM mytable