Oracle DB Query Custom Order by - sql

I'm looking for a way to accomplish something kind of like fuzzy search with Oracle. If this has already been answered, I'll gladly accept a link, but I'm so new to Oracle that I'm not even sure how to quickly search for what I want.
Given the following query:
SELECT VEND_CUST_CD, LGL_NM, ALIAS_NM
FROM {{DB_NAME}}.{{DB_TABLE}}
WHERE ({{condition_1}}) AND ({{condition_2}}) AND (upper(LGL_NM) LIKE upper('%{{term}}%')
ORDER BY LGL_NM
What I'd like to get in my response is a particular order. Let's imagine term=ze for the purposes of this.
I'd like to get results ordered like so:
Zealot Johnson
Zebra Eaters
Zero Gravity
Amazed John
Bedazzel
Lazer Sex
Zazew
So that what I'm getting back first is words that start with term followed by an alphabetical list of words that contain term within them.
I hope this is clear.

I suppose you can order the results like so:
ORDER BY CASE WHEN LGL_NM LIKE '{{term}}%' THEN 1 ELSE 2 END, LGL_NM

You can use union all like this:
select * from (
SELECT VEND_CUST_CD, LGL_NM, ALIAS_NM
FROM {{DB_NAME}}.{{DB_TABLE}}
WHERE ({{condition_1}}) AND ({{condition_2}}) AND (upper(LGL_NM) LIKE upper('{{term}}%')
union all
SELECT VEND_CUST_CD, LGL_NM, ALIAS_NM
FROM {{DB_NAME}}.{{DB_TABLE}}
WHERE ({{condition_1}}) AND ({{condition_2}}) AND (upper(LGL_NM) LIKE upper('{{%term%}}') AND (upper(LGL_NM) not LIKE upper('{{term%}}')
) order by ...
or like #Salman A 's way

Related

LIKE in multiple columns

I have columns title, description, keywords and I want to search a text in them.
I'm using PostgreSQL.
SELECT title FROM products
WHERE
ANY(ARRAY(title, description, keywords) like '%test%')
I'm getting error syntax error at or near "ANY".
I know I can do it with OR but I think that would not be the best way to do it.
I think I'm having errors at converting columns to array. Can someone give me an idea?Thanks!
Presumably, your goal is to only have the comparison '%test%' appear once. Here is one method:
WHERE EXISTS (SELECT 1
FROM UNNEST(ARRAY[p.title, p.description, p.keywords]) x
WHERE x LIKE '%test%'
)
Note that if you using equality, then IN suffices:
WHERE test IN (p.title, p.description, p.keywords)

How to specify a group of years in a table in SQL

Basic SQL question about specifying a group of years in a table. Working on a database and it is wanting me to list the author, title, publication date and retail price. I have that part down but its also ask to output all titles that start with "D" and were published in the 1970s.
I have the first part down: (this is how we are taught btw)
SELECT `fAuthorID`,`fTitle`,`fPubYear`,`fRetailPrice`
FROM `tBooks`
WHERE
But I cant seem to be able to get it to output the authors with a "D" and years 1970-1979 to display.
Assuming fpubyear is a number (integer) column, the correct way of querying for a continuous range of years is to use the BETWEEN operator.
SELECT fauthorID, fTitle, fPubYear, fReatailPrice
FROM tbooks
WHERE fTitle Like 'D%'
AND fPubYear BETWEEN 1970 and 1979;
The between operator includes both ends. It has the added benefit that an index on fpubyear can be used to quickly find the matching rows - which is not the case if the number first needs to be converted to a string to be able to apply the LIKE operator on it.
LIKE is for character values ("strings"), it should not be used with other types - especially not when relying on the evil implicit data type conversion. Other database would simply reject applying like on a number column.
SELECT fauthorID, fTitle, fPubYear, fReatailPrice
FROM tbooks
WHERE fTitle Like 'D%' AND fPubYear Like '197_'
Hi Dewie You an use this query,
SELECT fAuthorID,fTitle,fPubYear,fRetailPrice
FROM tBooks
WHERE fTitle like 'D%' and fPubYear like '%197%';
Hope this will give you result. Any issues just let me know

Can someone explain me which queries I need for a nice search in SQL?

I asked for a single query in my previous question but now I want to ask about multiple queries.
I'm making a search engine that searches through some specific tables.
When the input is "testone testtwo testthree" I will need to do a lot of queries.
a search with the complete string
a search with the 3 words in 3 strings ( if they can be seperately found in one item)
a search with 2 words in a combined string
a search with 2 words in 2 strings
a search with all words apart
As you know this decides what is a more important result.
I am building the queries seperately for all the 5 searches above as well as seperate for each table because a result from one table can be more important than from the other.
I made the queries like this:
SELECT *
FROM company_address
WHERE address_street LIKE '%test%'
OR address_zipcode LIKE '%test%'
OR address_telephone LIKE '%test%'"
OR address_fax LIKE '%test%'
OR address_website LIKE '%test%'
I know this is not the best way to do it, and because you guys are much better than me with this i would love some advice!
Even if you could do all of this in one query, it would be hard, if doable, to differentiate which result is more important(relevant) in that case.. so you either do requests separately, or go for some completely different solution.
Looks like you could use soemthing like Sphinx search server (it is used in conjuction with your RDBMS, MySQL most probably), it's opensource:
http://sphinxsearch.com/
Sphinx can search for phrases and sort results by relevance.
In the past I've done some trickery using CASE.
SELECT
*,
CASE WHEN address_street LIKE '%test%' THEN 1 ELSE 0 END
+
CASE WHEN address_zipcode LIKE '%test%' THEN 1 ELSE 0 END
+
CASE WHEN address_telephone LIKE '%test%' THEN 1 ELSE 0 END
+
CASE WHEN address_fax LIKE '%test%' THEN 1 ELSE 0 END
+
CASE WHEN address_website LIKE '%test%' THEN 1 ELSE 0 END
AS Score
FROM company_address
That gives you results with a score where the more matches there are, the higher the score, and you can give different scores to different matches. If you repeat the CASE statement in the ORDER BY or WHERE, you can narrow down your results.
This can get unwieldy pretty quick though, so be careful :)

No Exact match when using LIKE in SQL statement

SELECT bp.*,r.rating,COUNT(r.review_for),bp.business_name,bp.profile_member
FROM ibf_business_reviews r
LEFT JOIN ibf_business_profiles bp ON ( r.review_for=bp.profile_member )
WHERE bp.sub_category LIKE '%{$id},%'{$location_sql}
GROUP BY r.review_for HAVING COUNT(r.review_for) >=1
ORDER BY r.date_posted DESC LIMIT 0,2");
This query is used to show results for business_name in a certain sub_category id '%{$id} in a certain location. My problem is that extra results are showing in categories that share a second or third digit aka ...viewcat&id=54 will show in ..viewcat&id=154 etc
I using the LIKE may be my issue? WHERE bp.sub_category LIKE '%{$id},%'
You are storing a comma-separated list in a varchar, when you should store one number per row in a child table. Then you wouldn't have to use LIKE at all.
Read up on First Normal Form.
Here was my comment
+! for the need to reformat the SQL. You do realize that the "percent"
signs (%) are the wildcards. So you're
essentially telling it that you can
return ANYTHING that includes id... so
if you search "23" you could get
"123", you could get "234" or
"1234"... etc.
and you replied
Thanks #Rock removing the wildcards worked!
Now my answer to this is... If you removed BOTH wildcards from your string, then you're essentially doing an "equals".
IE:
WHERE bp.sub_category LIKE '{$id},'
should be the same as
WHERE bp.sub_category = '{$id},'
Because you don't have any wildcards to "match" in the "LIKE" statement.
Please forgive me if I screwed up the "$" or the ","... I'm not a MySQL guy

changing sorting criteria after the first result

I am selecting from a database of news articles, and I'd prefer to do it all in one query if possible. In the results, I need a sorting criteria that applies ONLY to the first result.
In my case, the first result must have an image, but the others should be sorted without caring about their image status.
Is this something I can do with some sort of conditionals or user variables in a MySQL query?
Even if you manage to find a query that looks like one query, it is going to be logicaly two queries. Have a look at MySQL UNION if you really must make it one query (but it will still be 2 logical queries). You can union the image in the first with a limit of 1 and the rest in the second.
Something like this ensures an article with an image on the top.
SELECT
id,
title,
newsdate,
article
FROM
news
ORDER BY
CASE WHEN HasImage = 'Y' THEN 0 ELSE 1 END,
newsdate DESC
Unless you define "the first result" closer, of course. This query prefers articles with images, articles without will appear at the end.
Another variant (thanks to le dorfier, who deleted his answer for some reason) would be this:
SELECT
id,
title,
newsdate,
article
FROM
news
ORDER BY
CASE WHEN id = (
SELECT MIN(id) FROM news WHERE HasImage = 'Y'
) THEN 0 ELSE 1 END,
newsdate DESC
This sorts the earliest (assuming MIN(id) means "earliest") article with an image to the top.
I don't think it's possible, as it's effectively 2 queries (the first query the table has to get sorted for, and the second unordered), so you might as well use 2 queries with a LIMIT 1 in the first.