Search for more than one column in the same query - sql

So I have a task to basically just by typing the first letter of the name or type on a table(product), show all the names that start with that letter or types that start with that letter.
Now the problem is: i dont know how to do it for the two columns(name, type)
basically all i have is this but i need to do the same for type in the same query. how tho?
SELECT id, type, name,price FROM product where name like 'cok%'

If I understood your question correctly, you are looking for a simple OR condition in your query:
SELECT id, type, name, price
FROM product
WHERE name ILIKE 'cok%' OR type ILIKE 'cok%'
Note I changed it from LIKE to ILIKE to make it case-insensitive, which seems to be more sensible in your case.

You probably need two queries if you want to show types that start with something and names that start with something. Or, if you want it combined, as in show all products where the name or the type starts with the letter, use OR:
SELECT id, type, name,price FROM product
WHERE name like 'cok%'
OR type like 'cok%'

Related

SQL - retrieval query for specific string

I am making a small database at the moment (less than 50 entries) and I am having trouble with a query. My query at the moment is
SELECT Name
FROM Customers
WHERE Name LIKE '%Adam%'
The names are in the format of "Adam West".
The query works fine in retrieving all the people with "Adam" in their name but I would like to only retrieve the first name, not the last name. I don't want to split the columns up but would like to know how to rewrite my query to account for this.
SELECT Name
FROM Customers
WHERE Name LIKE 'Adam%'
if you are storing name with space as separator example "Adam abcd" where 'Adam' is firstname and 'abcd' as lastname then following will work
SELECT Expr1
FROM (SELECT LEFT(Name, CHARINDEX(' ', Name, 1)) AS Expr1
FROM Customers) AS derivedtbl_1
WHERE (Expr1 LIKE 'Adm%')
for more details read this article http://suite101.com/article/sql-functions-leftrightsubstrlengthcharindex-a209089
If the name of your customers starts with first name (like Adam West) you can use
select Name
from Customers
where Name like 'Adam %'
Otherwise, if the format of the name is <last name> <first name> you can use
select Name
from Customers
where Name like '% Adam'
Try this
{SELECT Name
FROM Customers
WHERE SUBSTRING(Name,1,CHARINDEX(' ',Name)-1) LIKE '%Adam%'
}
I assumed the first name and last name is saparated by space and i took the firstname out
Using SUBSTRING(Name,1,CHARINDEX(' ',Name)-1)
and compared how you wanted. if your have something else saparating first name and last name change space in charindex with the saparater.
Please let me know if any other help needed.
Regards
Ashutosh
You should indeed "split" your columns and normalize your tables to avoid having to use complicated string functions to search for a lastname or firstname or what ever you need to look for. What about if someone entered lastname first and then firstname? Or just a nickname?
That said, check the use of LIKE on Microsoft technet site. The following query should be helpful on you case:
SELECT Name
FROM Customers
WHERE Name LIKE 'Adam%'

Fuzzy Duplicate Finding with SQLite

this is my first post and I'm something of a novice.
I'm trying to extract a list of fuzzy duplicates from and table of company names using SQLite with sqlite3.
For example, for a company like 'ZtPay' I'm currently using:
SELECT name FROM tab WHERE name LIKE 'Z_Pay');
SELECT name FROM tab WHERE name LIKE 'Zt_ay');
etc...
To account for typos.
My problem is that if there is no typo then I just output the original company name. Ideally I would like only to output the original name if there was a fuzzy duplicate found by the LIKE.
I know this is very wrong but I want something along the lines of:
SELECT name FROM tab WHERE name LIKE 'Z_Pay' IF ATLEAST 2 name LIKE 'Z_Pay'
Thanks in advance for any help you can give me.
You can determine if there is more than one name by looking at the min() and max():
SELECT name
FROM tab
WHERE name LIKE 'Zt_ay%'
group by name
having min(name) <> max(name)
Alternatively, you could use count(distinct):
SELECT name
FROM tab
WHERE name LIKE 'Zt_ay%'
group by name
having count(distinct name) > 1;

SQL query: Using DISTINCT/UNIQUE and SUM() in one statement

THE PROBLEM
I have four game servers collecting data. Putting data into a single table. Unfortunately this causes four entries per stat for one player.
WHAT I WANT
I want one record and SUM()on certain columns.
I will post a statement that I wrote which doesn't work but you'll get the point of what I would like to accomplish.
SELECT DISTINCT( Name ),
Max(Level),
Class,
Sum(Kills),
Sum(Deaths),
Sum(Points),
Sum(TotalTime),
Sum(TotalVisits),
CharacterID
FROM Characters
WHERE Name LIKE '$value%'
OR CharacterID LIKE '$value'
ORDER BY Name ASC;
Let me start by saying that duplicate rows in your database is truly less than ideal. A fully normalized database makes data much easier to manipulate without having random anomalies pop up.
However, to answer your question, this is simply what dweiss said put into code (using group by):
SELECT
name,
MAX(Level),
Class,
SUM(Kills),
SUM(Deaths),
SUM(Points),
SUM(TotalTime),
SUM(TotalVisits),
CharacterID
FROM
Characters
WHERE
Name LIKE '$value%' OR CharacterID LIKE '$value'
GROUP BY
name,
class,
characterid
ORDER BY
Name ASC
;
I'm assuming name, class, characterID, are all the same for each player, because that's the only way to get those values in there. Otherwise you'll have to use aggregate functions on them as well.
Instead of using distinct, you could group by your non-aggregated fields (ie name, class, characterid). This way you can use your aggregates: max, sum, and you will still have your distinct characters!

SQL wildcard matching excluding a specific pattern

sorry about the question I am a newbie to sql. i am attempting to create a search query for our database and I was wondering how would you filter certain words from your query for example:
Here is the sample data (the name column): Jean, Jain, Joan, Jorn, Juan, John, Juin
Lets say that we are searching for the names that start with "J" and end with "n" but we don't want to include "John".
SELECT id, name
FROM tblusers
WHERE name LIKE 'j__n'
WHERE name NOT LIKE 'John'
Obviously the above will have an error, so I was wondering how do I correctly write the above.
Thanks in advance.
SELECT id, name
FROM tblusers
WHERE name LIKE 'j%n'
AND name NOT LIKE 'John'

distinct sql query

I have a simple table with just name and email called name_email.
I am trying to fetch data out of it so that:
If two rows have the same name, but one has an email which is ending with ‘#yahoo.com’ and the other has a different email, then the one with the ‘#yahoo.com’ email should be discarded.
what would be best way to get this data out?
Okay, I'm not going to get involved in yet another fight with those who say I shouldn't advocate database schema changes (yes, you know who you are :-), but here's how I'd do it.
1/ If you absolutely cannot change the schema, I would solve it with code (either real honest-to-goodness procedural code outside the database or as a stored procedure in whatever language your DBMS permits).
This would check the database for a non-yahoo name and return it, if there. If not there, it would attempt to return the yahoo name. If neither are there, it would return an empty data set.
2/ If you can change the schema and you want an SQL query to do the work, here's how I'd do it. Create a separate column in your table called CLASS which is expected to be set to 0 for non-yahoo addresses and 1 for yahoo addresses.
Create insert/update triggers to examine each addition or change of a row, setting the CLASS based on the email address (what it ends in). This guarantees that CLASS will always be set correctly.
When you query your table, order it by name and class, and only select the first row. This will give you the email address in the following preference: non-yahoo, yahoo, empty dataset.
Something like:
select name, email
from tbl
where name = '[name]'
order by name, class
fetch first row only;
If your DBMS doesn't have an equivalent to the DB2 "fetch first row only" clause, you'll probably still need to write code to only process one record.
If you want to process all names but only the specific desired email for that name, a program such as this will suffice (my views on trying to use a relational algebra such as SQL in a procedural way are pretty brutal, so I won't inflict them on you here):
# Get entire table contents sorted in name/class order.
resultSet = execQuery "select name, email from tbl order by name, class"
# Ensure different on first row
lastName = resultSet.value["name"] + "X"
# Process every single row returned.
while not resultSet.endOfFile:
# Only process the first in each name group (lower classes are ignored).
if resultSet.value["name"] != lastName:
processRow resultSet.value["name"] resultSet.value["email"]
# Store the last name so we can detect next name group.
lastName = resultSet.value["name"]
select ne.*
from name_email ne
where ne.email not like '%#yahoo.com' escape '\' or
not exists(
select 1 from name_email
where name = ne.name and
email not like '%#yahoo.com' escape '\'
)
You could use something like the following to exclude invalid email addresses:
SELECT name, email
FROM name_email
WHERE email NOT LIKE '%#yahoo.com' // % symbol is a wildcard so joe#yahoo.com and guy#yahoo.com both match this query.
AND name = 'Joe Guy';
Or do it like this to include only the valid email address or domain:
SELECT name, email
FROM name_email
WHERE email LIKE '%#gmail.com'
AND name = 'Joe Guy';
This works well if you know ahead of time what specific names you are querying for and what email addresses or domains you want to exclude or include.
Or if you don't care which email address you return but only want to return one, you could use something like this:
SELECT DISTINCT (name, email)
FROM name_email;
You could do
SELECT TOP 1 email
FROM name_email
WHERE name = 'Joe Guy'
ORDER BY case when email like '%yahoo.com' then 1 else 0 end
So sort them by *#yahoo.com last and anything else first, and take the first one.
EDIT: sorry, misread the question - you want a list of each name, with only one email, and a preference for non-yahoo emails. Probably can use the above along with a group by, I'll have to rethink it.
Grabbing all the rows from the database, knowing not what the names are (and not needing to care about that really), but just want them to show, and if matching, skip a match if the email contains, in this case, #yahoo.com
SELECT DISTINCT name, email FROM name_email
WHERE email NOT LIKE '%#yahoo.com'
GROUP BY name;
Doing that will grab all the rows, but only one of a record if the names match with another row. But then, if there are two rows with matching names, junk the one with #yahoo.com in the email.
Not very pretty, but I believe it should work
select
ne.name
,ne.email
from
name_email ne
inner join (
select
name
,count(*) as emails_per_name
from
name_email
group by name
) nec
on ne.name = nec.name
where
nec.emails_per_name = 1
or (nec.emails_per_name > 1 and ne.email not like ('%#yahoo.com'))
That is assuming that the duplicate emails would be in yahoo.com domain - as specified in your question, and those would be excluded if there is more than one email per name
If you are working with SQL Server 2005 or Oracle, you can easily solve your problem with a ranking (analytical) function.
select a.name, a.name_email
from (select name, name_email,
row_number() over (partition by name
order by case
when name_email like '%#yahoo.com' then 1
when name_email like '%#gmail.com' then 1
when ... (other 'generic' email) then 1
else 0
end) as rn) as a
where a.rn = 1
By assigning different values to the various generic email names you can even have 'preferences'. As it is written here, if you have both a yahoo and a gmail address, you can't predict which one will be picked up.
You could use a UNION for this. Select everything without the yahoo.com and then just select the records that have yahoo.com and is not in the first list.
SELECT DISTINCT (name, name_email) FROM TABLE
WHERE name_email NOT '%yahoo.com'
UNION
SELECT DISTINCT (name, name_email) FROM TABLE
WHERE name NOT IN (SELECT DISTINCT (name, name_email) FROM TABLE
WHERE name_email NOT '%yahoo.com')