select attributes which are a substring of a constant - database

I am faced with a database (sqlite specifically) query that I am not sure how to approach.
I am looking for all tuples who's name attribute is a substring of some provided constant.
For example it is a database containing food items. If the constant is "Maranatha Natural Almond Butter 26oz Lightly Roasted" I would like any tuple in the database that contains the words "Almond Butter", "Maranatha Natural", etc to be returned as matches.
I really am at a loss for how to approach this problem efficiently and any help would be greatly appreciated.

Use LIKE, but the other way around:
SELECT *
FROM mytable
WHERE 'Maranatha Natural Almond Butter 26oz Lightly Roasted' LIKE '%' || name || '%'

I recommend you give full-text searching a try. In your examples you wouldn't necessarily need it as LIKE might be sufficient. However, if you want to match only exact words (say you search for set you may not want setting matched) and if you want to match multiple words wherever they appear in your descriptions, FTS can be very helpful. Before using it, verify that your implementation is compiled with it:
sqlite> pragma compile_options;
CURDIR
ENABLE_FTS3 <---- this one has to appear
ENABLE_RTREE
TEMP_STORE=1
THREADSAFE=0
Say you have the FTS table FoodItemsFTS populated with the food item you mentioned earlier:
sqlite> CREATE VIRTUAL TABLE FoodItemsFTS USING fts3();
sqlite>
sqlite> INSERT INTO FoodItemsFTS (docid, content)
VALUES (1, "Maranatha Natural Almond Butter 26oz Lightly Roasted");
sqlite> INSERT INTO FoodItemsFTS (docid, content)
VALUES (2, "Maranatha Natural Almond Butter 26oz");
sqlite>
sqlite> SELECT docid FROM FoodItemsFTS WHERE FoodItemsFTS MATCH 'Almond Roasted';
1
sqlite>

Related

Sqlite giving same output and not considering where clause order

I want to get the entry from database using sqlite3 using sqlite_prepare_v2() in c interface and used to get the out put not in the expected order.
want to get the entry in the exact order in which size is given in the where clause but behavior is as below:
sqlite> select id,size from audio where size in (9,16,8);
3|9
4|8
5|16
sqlite>
sqlite> select id,size from audio where size in (8,9,16);
3|9
4|8
5|16
sqlite>
sqlite> select id,size from audio where size in (16,8,9);
3|9
4|8
5|16
For the first query, I am expecting the ouput to be in other order of size inside the where clause, but is seems sqlite is by default always giving the output in the order of the id. here id is the primary key field. Is sqlite using any default indexing on primary key field making this to happen? or is there a way to get the output from the sqlite as it is given in the where clause? Please let me know. Thanks.
The order of the in() clause is irrelevant to the order of the select results.
In order to get the select results in the desired order, you must either add an explicit order by clause that fits your need, such as order by size in the second case, or you must issue 3 separate select statements in the desired order.

SQL Comparing Data Keywords

Good morning,
I have been searching all over google for an answer to this so was wondering if anyone could help me out? Basically I have a database table, which consolidates keywords for example: dog, cat, horse, mouse. This is displayed as a result. However I need to create some SQL to say if two of those keywords exists, e.g horse and cat, then display these results. This would then allow us to go down X route.
Another example or issue which is a work around is to have a list of keywords, and then store this as a value, this would mean if someone typed in: my dog is violently attacking neighbours cats, it would detect dog and cat and would bring the user to a specific outcome..
declare #teststring varchar(512) = '{KEYWORD}'
select top 1 k.type
from (values
('pet', '1'), ('dog', '1'), ('cat', '1')
) k(word,type) where #teststring like '%' + k.word + '%'
group by k.type
HAVING COUNT(1) >=2
order by COUNT(1) desc
As you can see this is storing cat, dog and pet. This then means if someone types my pet is a dog then it would go down a conditional route. (We then store the answers people put into {Keyword1}
So my issue here is I am limited to characters I can use in my SQL field. So I have created two lists (one list above with pet cat and dog.). Another list I have has exactly the same but (rabbit, hamster and horse). This is stored in {Keyword2} I want to be able to write some SQL that says if any of the keywords in {Keyword1} and {Keyword2} have been entered to then go down a specific conditional route. so if someone types by rabbit has been attacked by my dog it would detect rabbit and dog and would make this conditional and go down there.
I hope this isn't too confusing? I have thought about nested sql and inner joins but I am not sure this will do what im asking.
I'm not sure where's your problem, you seem to have it already covered, unless, you're having trouble making actionable code?
Maybe do this first:
Dispose of order by COUNT(1) desc,
Change >=2 to >=1,
Add your other keywords after cat with a different number, for example ('cat', '1'), ('keys', '2'), ('shirt', '2'),
Replace top 1 k.type with any placebo, like 1 or 'A',
Then, add this afterwards:
IF ##ROWCOUNT >= 2
/* Do some stuff, because both keywords were used */
The concept is, if you wanna conditionally run some code, you'll usually need IF / ELSE, perhaps sometimes you can instead use TRY / CATCH or loops.
The ##ROWCOUNT isn't the mainstream way of checking in an IF, but it makes do many times, and I wanted to intervene on your code the least amount possible, for now. I might be even not getting you right to begin with.
The changes on your original query were aimed to have it produce an amount of records corresponding to how many keyword groups were found. Later on, that would be contested against ##ROWCOUNT as you have probably seen.
Hope I helped. All of this can be better done for sure, maybe when we can confirm what you're looking for.
If you can store you keywords as tables you can use intersect:
DECLARE #table1 TABLE (KeyWord VARCHAR (100))
DECLARE #table2 TABLE (KeyWord VARCHAR (100))
INSERT INTO #table1
VALUES
('dog'),('rabbit'),('dragon'),('cat')
INSERT INTO #table2
VALUES
('dog'),('rabbit'),('ogre'),('whale')
SELECT KeyWord FROM #table1
INTERSECT
SELECT KeyWord FROM #table2

How would I determine if a varchar field in SQL contains any numeric characters?

I'm working on a project where we have to figure out if a given field is potentially a company name versus an address.
In taking a very broad swipe at it, we are going under the assumption that if this field contains no numbers, odds are it is a name vs. a street address (we're aiming for the 80% case, knowing some will have to be done manually).
So now to the question at hand. Given a table with, for the sake of simplicity, a single varchar(100) column, how could I find those records who have no numeric characters at any position within the field?
For example:
"Main Street, Suite 10A" --Do not return this.
"A++ Billing" --Should be returned
"XYZ Corporation" --Should be returned
"100 First Ave, Apt 20" --Should not be returned
Thanks in advance!
Sql Server allows for a regex-like syntax for range [0-9] or Set [0123456789] to be specified in a LIKE operator, which can be used with the any string wildcard (%). For example:
select * from Address where StreetAddress not like '%[0-9]%';
The wildcard % at the start of the like will obviously hurt performance (Scans are likely), but in your case this seems inevitable.
Another MSDN Reference.
select * from table where column not like '%[0-9]%'
This query returns you all rows from table where column does not contain any of the digits from 0 to 9.
I like the simple regex approach, but for the sake of discussion will mention this alternative which uses PATINDEX.
SELECT InvoiceNumber from Invoices WHERE PATINDEX('%[0-9]%', InvoiceNumber) = 0
This worked for me .
select total_employee_count from company_table where total_employee_count like '%[^0-9]%'
This returned all rows that contains non numeric values including 2-3 ..
This Query to list out Tables created with numeric Characters
select * from SYSOBJECTS where xtype='u' and name like '%[0-9]%'

Need help with Sql Server Full Text Search problem

I have a Full Text Catalog on single table, with three fields defined :-
TABLE: Animals
Fields: Name, Breed, LatinName.
Now, the Catalog seems to be working perfectly.
eg.
CREATE FUNCTION AnimalSearch
(
#Name NVARCHAR(200)
) RETURNS TABLE AS
RETURN
(
SELECT KEY_TBL.[Key] as Name,
KEY_TBL.RANK as Relevance
FROM CONTAINSTABLE(Animals, Name, #Name) AS KEY_TBL
)
Now, when i run this, i get the following results :-
Name = ma (no results)
Name = mat (no results)
Name = matt (1 result - correct).
SELECT * FROM [dbo].[AnimalSearch]('ma')
Is this the correct way to use this? I've also tried replacing CONTAINSTABLE with FREETEXTTABLE .. same thing .. no results.
Any ideas, anyone?
Edit
I understand that this could be achieved in a stored proc. I'm was hoping to do this as a Table-Valued Function, so i could use this in some Linq2Sql. If it's really unperformant, then please say so.
Not sure it's a good idea. Table valued functions do not store statistics, so performance may suffer.

What is a SQL "pseudocolumn"?

I accidentally coded SELECT $FOO.. and got the error "Invalid pseudocolumn "$FOO".
I can't find any documentation for them. Is it something I should know?
Edit: this is a MS SQL Server specific question.
Pseudocolumns are symbolic aliases for actual columns, that have special properties, for example, $IDENTITY is an alias for the column that has the IDENTITY assigned, $ROWGUID for the column with ROWGUIDCOL assigned. It's used for the internal plumbing scripts.
I don't know why most of the answers are Oracle specific the Question is about SQL Server!
As well as RobsonROX's answer an other example of their use is in the output clause of a merge statement. $action indicates whether the row was inserted or deleted.
A pseudocolumn behaves like a table column, but is not actually stored in the table. You can select from pseudocolumns, but you cannot insert, update, or delete their values.
A simple Google search brings up this from Oracle's reference:
A pseudocolumn behaves like a table
column, but is not actually stored in
the table. You can select from
pseudocolumns, but you cannot insert,
update, or delete their values.
I think that the error you got is simply because there is no column $FOO, so the query parser tests to see if there's a psuedocolumn named $FOO as a fallback. And since there is no pseudocolumn named "$FOO" (and there are no other fallback) you get the error "Invalid pseudocolumn $FOO". This is a guess, though. I'm no expert when it comes to databases.
Pseudocolumns are virtual columns that are available in special cases. In an Oracle database, there's a ROWNUM pseudocolumn that will give you the row number. SQL server, as far as I know, doesn't actually support pseudocolumns but there are errors and stored procedures that refer to pseudo columns, probably for Oracle migration.
One example of a pseudo-column is ROWID in Informix. It is a 32-bit number that can be used to find the data page more quickly than any other way (subject to caveats, such as the table is not fragmented) because it is basically the page address for the data. You can do SELECT * FROM SomeTable and it won't show up; you can do SELECT ROWID, * FROM SomeTable and it will show up in your data. Because it is not actually stored on disk (you won't see the ROWID on the disk with the data, though the ROWID tells you where to look on the disk for the data), it is a pseudo-column. There can be other pseudo-columns associated with tables - they tend to be similarly somewhat esoteric.
They can also be called hidden columns, particularly if they are (contrary to pseudo-columns) actually stored in the database, but are not selected by *; you have to specifically request the column to see it.
pseudo columns are the false columns.
any table will support pseudo columns as same to that of it own column
strictly speaking they are functions:
1.SYSDATE;
2.ROWNUM;
3.ROWID;
4.NEXTVAL;
5.CURRVAL;
6.LEVEL;
Suppose, we have a situation where number of columns are not same in two tables, and we need to apply UNION then generally we take help of Pseudo columns just to perform UNION operation.
Select Col1, Col2, Col3, Col4, Col5 from Table1
UNION
Select Col1, Col2, Col3, Null as Col4, Null as Col5 from Table2

Resources