MySQL, select records with at least X characters matching - mysql

I am trying to accomplish the following. Let's say we have a table that contains these fields (ID, content)
1 | apple
2 | pineapple
3 | application
4 | nation
now, I am looking for a function that will tell me all possible common matches. For example, if the argument is "3", the function will return all possible strings from 3 characters that appear in more then one record.
In this case, I get "app","ppl","ple","ati","tio","ion"
If the argument is "4", i get: "appl","pple","atio","tion"
If the arugment is "5", i get: "apple","ation"
If the argument is "6", nohting is returned.
Untill now, I did not find a function that accomplishes this.
Thx!
Some extra information:
I am using this in a PHP script with a MySQL database. I really just want to give the amount of characters as an argument and of course the table to search in.

Well, this is kind of ugly, but it does work fine. It's generic SQL and will work in any environment. Simply generate a number of selects of a substring that is greater than the maximum length of the field that you're reading. Change the number 50 in the function to a number that exceeds your fieldlength. It may return a realllly long query, but like I said, it'll work fine. Here is an example in Python:
import sqlite3
c = sqlite3.connect('test.db')
c.execute('create table myTable (id integer, content varchar[50])')
for id, content in ((1,'apple'),(2,'pineapple'),(3,'application'),(4,'nation')):
c.execute('insert into myTable values (?,?)', [id,content])
c.commit();
def GenerateSQL(substrSize):
subqueries = ["select substr(content,%i,%i) AS substr, count(*) AS myCount from myTable where length(substr(content,%i,%i))=%i group by substr(content,%i,%i) " % (i,substrSize,i,substrSize,substrSize,i,substrSize) for i in range(50)]
sql = 'select substr FROM \n\t(' + '\n\tunion all '.join(subqueries) + ') \nGROUP BY substr HAVING sum(myCount) > 1'
return sql
print GenerateSQL(3)
print c.execute(GenerateSQL(3)).fetchall()
The query generated looks like:
select substr FROM
(select substr(content,0,3) AS substr, count(*) AS myCount from myTable where length(substr(content,0,3))=3 group by substr(content,0,3)
union all select substr(content,1,3) AS substr, count(*) AS myCount from myTable where length(substr(content,1,3))=3 group by substr(content,1,3)
union all select substr(content,2,3) AS substr, count(*) AS myCount from myTable where length(substr(content,2,3))=3 group by substr(content,2,3)
union all select substr(content,3,3) AS substr, count(*) AS myCount from myTable where length(substr(content,3,3))=3 group by substr(content,3,3)
union all select substr(content,4,3) AS substr, count(*) AS myCount from myTable where length(substr(content,4,3))=3 group by substr(content,4,3)
... )
GROUP BY substr HAVING sum(myCount) > 1
And the results it produces are:
[(u'app',), (u'ati',), (u'ion',), (u'nat',), (u'pin',), (u'ple',), (u'ppl',), (u'tio',)]

I'm sorry as I haven't been playing with php for a while & I don't have a proper test environment for it, but I quickly devised a way of doing this in c# 3.5
pseudocode: build a table with strings of the specified length & a count of occurences next to it. Select where count > 1:
static void Main(string[] args)
{
string[] data = { "apple", "pinapple", "application", "nation" };
string[] result = my_func(3,data);
foreach (string str in result)
{
Console.WriteLine(str);
}
Console.ReadKey();
}
private static string[] my_func(int l, string[] data)
{
Dictionary<string,int> dict = new Dictionary<string,int>();
foreach (string str in data)
{
for (int i = 0; i < str.Length - l + 1; i++)
{
string part = str.Substring(i, l);
if (dict.ContainsKey(part))
{
dict[part]++;
}else {
dict.Add(part,1);
}
}
}
var result = from k in dict.Keys
where dict[k] > 1
orderby dict[k] descending
select k;
return result.ToArray<string>();
}

One obvious option is to use REGEX. I have no prior experience in this but this might be of help to you:
http://dev.mysql.com/doc/refman/5.1/en/regexp.html
You'll need to find a suitable expression to match what you need.

Related

check if select statement is true in a function in pl/sql

so i have a table called cars designed like this: ID, Model, Category, Availability.
The categories are standard and luxury.
im trying to write a function that returns either a boolean or an int like this :
function(id)
if category == luxury;
return 1;
else return 0;
i did this select statement but i dont know if i can use it
SELECT (CASE WHEN Category = 'Luxury' THEN 1 ELSE 0 END) AS is_equal
FROM CARS
WHERE ID = 'TM63DTI';
I have to do it in pl/sql. its for a school project and im stuck at this point. I dont have an error with this select statement, i just dont really know how to use it. Maybe suggest an idea of how i can approach this.
PL/SQL means "Oracle", not "MySQL". I suggest you fix tags.
So, if it really is Oracle, then one option might be this:
create or replace function f_category
(par_id in cars.id%type)
return boolean
is
l_is_equal number;
begin
select case when category = 'Luxury' then 1
else 0
end
into l_is_equal
from cars
where id = par_id;
return l_is_equal = 1;
end;
/
Though, it is kind of difficult to use a function that returns Boolean in SQL, so - perhaps you'd also want to consider option that returns a number instead. It is simple to convert previous function to a new version:
create or replace function f_category
(par_id in cars.id%type)
return number
is
l_is_equal number;
begin
select case when category = 'Luxury' then 1
else 0
end
into l_is_equal
from cars
where id = par_id;
return l_is_equal;
end;
/
Now you can use it in SQL as e.g.
select f_category(par_id => 123) from dual;
or
select *
from cars
where f_category(id) = 1;

SQL + goLang - running select statement with an IN condition - and passing it an array of ids?

I want to perform the following logic -
SELECT some_column
FROM table_name
WHERE id IN (value1, value2, ...);
in my go code I have the following int array to represent my ids :
idsToGet := []int{1,2}
I fully understand that you might normally do a sprintf and pass in the one id you were looking for... BUT...
I feel like there is a sensible way to do this without iterating over the array, and doing this as a separate call for each ID... via sprintf - is there a way I can do this as just one call - and have my IN clause auto contain everything from my array?
Totally new to Go - been trying to solve this for an hour, I have it working for single id's - but not for multiples.
You don't want to use Sprintf to put raw values into SQL, that's a bad habit. What you want to do is build a bit of SQL with the right number of placeholders and then let the library take care of replacing the placeholders with their value.
If you have two ints in your array then you want to build this:
SELECT some_column
FROM table_name
WHERE id IN (?, ?)
If you have four then you want to build:
SELECT some_column
FROM table_name
WHERE id IN (?, ?, ?, ?)
and so on. All you need is a simple function that can produce n placeholders; there are lots of ways to do this:
func placeholders(n int) string {
ps := make([]string, n)
for i := 0; i < n; i++ {
ps[i] = "?"
}
return strings.Join(ps, ",")
}
or maybe:
func placeholders(n int) string {
var b strings.Builder
for i := 0; i < n - 1; i++ {
b.WriteString("?,")
}
if n > 0 {
b.WriteString("?")
}
return b.String()
}
or whatever is clearest to you, the implementation is unlikely to have any measurable impact as long as it is correct.
Then you can say things like:
query := fmt.Sprintf("select some_column from table_name where id in (%s)", placeholders(len(idsToGet)))
rows, err := db.Query(query, idsToGet...)
and spin throw rows in the usual manner.

How do I write a Linq to SQL query with a cast?

How do i write a Linq to SQL query that translates into the following:
SELECT CAST(DATETEXT AS datetime) FROM mytable
var dates = from row in mytable
select DateTime.Parse(row.DATETEXT);
There are method overloads for DateTime.Parse that allow you to specify a format.
actually, you won't be needing that. just parse it as datatime when you will use the field value. here is an exaple;
var query = from c in mytable
select c;
then when you will use it;
DateTime _value = (DateTime)query.SingleOrDefault().DATETEXT
but if you wanna use it so much. here is an example;
NorthwindEntities _e = new NorthwindEntities();
public void poo() {
var query = from e in _e.Products
select DateTime.Parse(e.DateText);
}

Linq To Sql - Dynamic

I have two Tables:
Table 1: Client
Fields: Id_Client Char 5 Name_Client
Char 50
Table 2: Country
Fields: Id_Country Char 4 Name_Country
Char 80 Population Int 15
With Sql I can make this 2 queries
Select Id_Client, Name_Client from
Client
Select Id_Country, Name_Country,
Population from Country
I wan to do this 2 queries in only one using Linq SQL.
I think something like this
string Option = "";
string SelectFields = ""; string
TableName = "";
if (Option == "Client"){
SelectFields = "Id_Client, Name_Client";
TableName = "Client";
}
else{
SelectFields = "Id_Country, Name_Country, Population";
TableName = "Country";
}
Select "SelectFields" from "TableName"
I'm a Visual Fox Pro Developer and using Evaluate (macros) this is very easy to do. Is possible to do something like this on Linq To Sql???
Sorry for my poor english
You will want to look into dynamic linq to sql, this will allow you to pass in the expression as a string.
In the end you will end up with something like the following:
IQueryable<SomeItem> = results = context.SomeItem.Where("SomeItemID > 30 AND SomeItemID < 40");
Additional Information, Using Dynamic Linq

What's the Linq to SQL equivalent to TOP or LIMIT/OFFSET?

How do I do this
Select top 10 Foo from MyTable
in Linq to SQL?
Use the Take method:
var foo = (from t in MyTable
select t.Foo).Take(10);
In VB LINQ has a take expression:
Dim foo = From t in MyTable _
Take 10 _
Select t.Foo
From the documentation:
Take<TSource> enumerates source and yields elements until count elements have been yielded or source contains no more elements. If count exceeds the number of elements in source, all elements of source are returned.
In VB:
from m in MyTable
take 10
select m.Foo
This assumes that MyTable implements IQueryable. You may have to access that through a DataContext or some other provider.
It also assumes that Foo is a column in MyTable that gets mapped to a property name.
See http://blogs.msdn.com/vbteam/archive/2008/01/08/converting-sql-to-linq-part-7-union-top-subqueries-bill-horst.aspx for more detail.
Use the Take(int n) method:
var q = query.Take(10);
The OP actually mentioned offset as well, so for ex. if you'd like to get the items from 30 to 60, you would do:
var foo = (From t In MyTable
Select t.Foo).Skip(30).Take(30);
Use the "Skip" method for offset.
Use the "Take" method for limit.
#Janei: my first comment here is about your sample ;)
I think if you do like this, you want to take 4, then applying the sort on these 4.
var dados = from d in dc.tbl_News.Take(4)
orderby d.idNews descending
select new
{
d.idNews,
d.titleNews,
d.textNews,
d.dateNews,
d.imgNewsThumb
};
Different than sorting whole tbl_News by idNews descending and then taking 4
var dados = (from d in dc.tbl_News
orderby d.idNews descending
select new
{
d.idNews,
d.titleNews,
d.textNews,
d.dateNews,
d.imgNewsThumb
}).Take(4);
no ? results may be different.
This works well in C#
var q = from m in MyTable.Take(10)
select m.Foo
Whether the take happens on the client or in the db depends on where you apply the take operator. If you apply it before you enumerate the query (i.e. before you use it in a foreach or convert it to a collection) the take will result in the "top n" SQL operator being sent to the db. You can see this if you run SQL profiler. If you apply the take after enumerating the query it will happen on the client, as LINQ will have had to retrieve the data from the database for you to enumerate through it
I do like this:
var dados = from d in dc.tbl_News.Take(4)
orderby d.idNews descending
select new
{
d.idNews,
d.titleNews,
d.textNews,
d.dateNews,
d.imgNewsThumb
};
You would use the Take(N) method.
Taking data of DataBase without sorting is the same as random take
Array oList = ((from m in dc.Reviews
join n in dc.Users on m.authorID equals n.userID
orderby m.createdDate descending
where m.foodID == _id
select new
{
authorID = m.authorID,
createdDate = m.createdDate,
review = m.review1,
author = n.username,
profileImgUrl = n.profileImgUrl
}).Take(2)).ToArray();
I had to use Take(n) method, then transform to list, Worked like a charm:
var listTest = (from x in table1
join y in table2
on x.field1 equals y.field1
orderby x.id descending
select new tempList()
{
field1 = y.field1,
active = x.active
}).Take(10).ToList();
This way it worked for me:
var noticias = from n in db.Noticias.Take(6)
where n.Atv == 1
orderby n.DatHorLan descending
select n;