SQL multiple words search, ordered by number of matches - sql

I'm trying to compose an SQL SELECT query with multiple search words. But I want the result be ordered by number of words matches.
For example, let the search string is "red green blue". I want the results which contains all these three words on top, after that the results, which contains two of them, and at the end - only one word matches.
SELECT
*
FROM
table
WHERE
(col LIKE '%red%') OR
(col LIKE '%green%') OR
(col LIKE '%blue%')
ORDER BY
?????
Thanks in advance!

ORDER BY
(
CASE
WHEN col LIKE '%red%' THEN 1
ELSE 0
END CASE
+
CASE
WHEN col LIKE '%green%' THEN 1
ELSE 0
END CASE
+
CASE
WHEN col LIKE '%blue%' THEN 1
ELSE 0
END CASE
) DESC
If your DB vendor has IF, you can use it instead of CASE (e.g., for Mysql you can write
IF (col LIKE '%red% , 1,0) + IF(....'

What platform are you using? if SQL Server, then it sounds like a Full Text Search archtecture would be your best fit.
http://msdn.microsoft.com/en-us/library/ms142583.aspx

Related

Read multiple columns from single table based on our input string

I want to select multiple columns from single table based on my given input string in sql select statement.
Example :
If input="table_medical" i want to select the columns like medi_col1,medi_col2,medi_col2
If input="table_pharmacy" i want to select the columns like medi_phar1,medi_phar2,medi_phar1
sql("select
case when $input="table_medical" then medi_col1) //like this
please help me to complete this.
If you want this in a single query, then the same number of columns is needed -- and have compatible types.
One method uses union all:
select medi_col1, medi_col2, medi_col2
from t
where #input = 'table_medical'
union all
select medi_phar1, medi_phar2, medi_phar1
from t
where #input = 'table_pharmacy';
SET #input="table_medical";
SELECT
CASE WHEN #input="table_medical" THEN medi_col1 ELSE medi_phar1 END as medi_col1,
CASE WHEN #input="table_medical" THEN medi_col2 ELSE medi_phar2 END as medi_col2
CASE WHEN #input="table_medical" THEN medi_col3 ELSE medi_phar3 END as col3
FROM MyTable
Data types for medi_col1 and medi_phar1 needs to be same (and for the rest of columns too)

SQL query to sort data while insert , first numbers then alphabets an last symbols

I am getting trouble to write SQL sort Query,
I have table as follows
And I want to sort above data as, First should number and then alphabets and last special symbols like following table.
First numbers should sort like 1,2,3,11,22,33
then Alphabets should sort like a ,b,c,..z
and then symbols,
like following table
I have tried many ways but still not getting correct way, please help me to write query.
You can use a CASE WHEN on the ORDER BY to create some groups:
SELECT *
FROM table_name
ORDER BY
CASE WHEN LEFT(FilterParameterValue, 1) LIKE '[0-9]' OR LEFT(FilterParameterValue, 2) LIKE '-[0-9]' OR LEFT(FilterParameterValue, 2) LIKE '+[0-9]' THEN 1 ELSE 0 END DESC, -- group for numbers
CASE WHEN ISNUMERIC(FilterParameterValue) = 1 THEN CAST(FilterParameterValue AS MONEY) ELSE NULL END ASC, -- order the numeric values
CASE WHEN LEFT(FilterParameterValue, 1) LIKE '[A-Za-z]' THEN 1 ELSE 0 END DESC, -- group for chars from A to Z (capital / non capital)
colName
demo on dbfiddle.uk
Try using regex in order by clause.. For ex
ORDER BY IF(FilterParameterValue RLIKE '^[a-z]', 1, 2), FilterParameterValue
You can try to cast your Column to Numeric Type then ordered
SELECT * FROM table_name ORDER BY TRY_CAST(Column_Name as Type)

Dynamic Label in Select

I was wondering if we can change the label of the select statement like we do for data in sql select using CASE
SELECT CASE column1 = 1 THEN 1 ELSE 0 END AS [Available]
But can we have a dynamic header something like
SELECT column1 AS <-- Available when 1 or Not Available when 0
This can be handled on the front end but its wise if we have it on backend. Any help or useful link is appreciated
You can do it with dynamic sql and if...else instruction but it not make sense for me. In relational database value in the cell tells you if something is available or not. If header tells you the same as cell it's duplicate information. If you want to description of the value you can use case syntax instead of 0/1 value
SELECT CASE when column1 = 1 THEN 'Available'
ELSE 'Not available'
END AS [Available]
Well, that would not make sense, as what would you expect the column name to be if you hade 2 rows, one with 1 (being available) and the other with 0(being Not Available)?
You would have to stick to something like
SELECT
CASE
WHEN column1 = 1
THEN 'Available'
ELSE 'Not available'
END as Availability
FROM YourTable

How to quickly compare many strings?

In SQL Server, I have a string column that contains numbers. Each entry I need is only one number so no parsing is needed. I need some way to find all rows that contain numbers from 400 to 450. Instead of doing:
...where my stringcolumn like '%400%' or stringcolumn like '%401%' or stringcolumn like '%402%' or ...
is there a better that can save on some typing?
There are also other values in these rows such as: '5335154', test4559#me.com', '555-555-5555'. Filtering those out will need to be taken into account.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn = '450'
You don't need the wildcard if you want to restrict to 3 digits.
Use regex to accomplish this.
...where stringcolumn like '4[0-4][0-9]' OR stringcolumn like '450'
one way
WHERE Column like '%4[0-4][09]%'
OR Column LIKE '%500%'
keep in mind that this will pick anything with the number in it, so 5000 will be returned as well
I would do the following:
select t.*
from (select t.*,
(case when charindex('4', col) > 0
then substrint(col, charindex('4', col), charindex('4', col) + 2)
end) as col4xx
from t
) t
where (case when isnumeric(col4xx) = 1
then (case when cast(col4xx as int) between 400 and 450 then 'true'
end)
end) = 'true'
I'm not a fan of having case statements in WHERE clauses. However, to ensure conversion to a number, this is needed (or the conversion could become a column in another subquery). Note that the following is not equivalent:
where col4xx between '400' and '450'
Since the string '44A' would match.

SQLServer - Select bool if column begins with a string

I would like to select a boolean of whether or not a column begins with a certain string.
SELECT (name LIKE 'foo%') AS isFoo FROM bar;
Is there a way to do this without using an inline CASE?
No
There is neither implicit boolean CAST in SQL Server nor a boolean type
SELECT CAST(CASE WHEN name LIKE 'foo%' THEN 1 ELSE 0 END AS bit) AS isFoo
FROM bar;
You might not even need the cast depending on your usage:
SELECT CAST(PATINDEX('foo%'), name) AS bit) FROM bar
This will return 1 if the col starts with the text otherwise 0. No CASE involved.
A UNION operation would let you skip a CASE statement by combining two result sets. In the first query you filter for all rows that match 'foo%' and in the second you match all rows that do not match 'foo%'
Something like:
SELECT 1 AS [YourBoolean], 'fool' WHERE 'fool' LIKE 'foo%'
UNION
SELECT 0, 'fuel' WHERE 'fuel' NOT LIKE 'foo%'
ORDER BY 1
(Hard-coded example w/o target table.)
Create a User Defined function that you can call inorder to check if the name contains foo.
Not to take away from what gbn suggested but I think this would be more efficient (but essentially the same thing)
SELECT CAST(CASE WHEN LEFT(name, 3)='foo' THEN 1 ELSE 0 END AS bit) AS isFoo
FROM bar;
SELECT
CASE WHEN name LIKE 'foo%'
THEN 1
ELSE 0
END as isFoo
FROM bar