How to use multiple placeholder values with LIKE sql in mysqljs/mysql? - node-mysql

It's easy to get this to work if there's only one placeholder value. For example:
con.query('select * from user where firstname like ?', "%" + firstname + "%", (err, result) => {
// do something
});
If you have two placeholders, you need to put them in an array, like so:
con.query('select * from user where firstname = ? and lastname = ?', ['Joe', 'Bloggs'], (err, result) => {
// do something
});
How can I convert this query so it will work with like? In other words, how can I get this to work:
con.query('select * from user where firstname like ? and lastname like ?', myArray, (err, result) => {
// do something
});
I need to somehow make myArray act like ['%Joe%', '%Bloggs%'].
Thank you.

I know it's late, but it maybe useful with someone with same question.
You can use something like this
"SELECT * FROM user WHERE firstname LIKE concat('%' , ?, '%') and lastname LIKE concat('%' , ?, '%')"

Related

How to use bindings in a whereRaw query?

I have a table with two columns, 'first_name' and 'last_name' and I want to join both tables so that I can search a query against them with a LIKE query and using % wildcards.
I was able to do this when I used a string literal, however it is not working when I'm trying to use positional bindings. I am returned with nothing.
Is there a way to join the two columns without concat and a whereRaw function? And how would I write the binding correctly?
const searchUser = (query) => {
const name = query.toLowerCase();
return knex('users')
.select('*')
.whereRaw('concat(LOWER("first_name"), \' \' , LOWER("last_name")) LIKE \'%??%\'', [name]);
};
It appears that you may be trying to query two separate columns with the same value?
What you could do here is a orWhere chain which links multiple where statements together where it matches if just one is true.
For example:
const searchUser = (query) => {
return knex('users')
.select('*')
.where(knex.raw('first_name ILIKE ?', `%${query}%`))
.orWhere(knex.raw('last_name ILIKE ?', `%${query}%`));
};
This also uses "ILIKE" which gets you the same case insensitive matching that you're achieving with the LOWER function.
You may also find value using a named binding rather than positional bindings. This would look like this:
const searchUser = (query) => {
const bindings = { query: `%${query}%` };
return knex('users')
.select('*')
.where(knex.raw('first_name ILIKE :query', bindings))
.orWhere(knex.raw('last_name ILIKE :query', bindings));
};

Find all rows which match substring, with moor / moor_flutter

I want to select all rows which match a substring with moor / moor_flutter.
In SQL, you'd do something like this:
'SELECT * FROM [table] WHERE [field] LIKE '%[substring]%'
Is there a 'moor-like' way of doing this?
The closest I've come, is this:
Stream<List<Task>> watchTable() {
return (select(tableItem)..where((tbl) => CustomExpression<bool>("field LIKE '%substring%'"))).watch();
}
But unfortunately that's not a nice typesafe / moor-like way.
Here is the example what I have done for like query:
// Get all the doctors [by optional params city and area]
Future<List<DoctorMaster>> getAllDoctors({String city = "", String area = ""}) {
return (select(doctorMasters)..where((tbl) => tbl.city.like(city) & tbl.area.like(area))).get();
}
You can do something like that for your purpose.
Stream<List<Task>> watchTable() {
return (select(tableItem)..where((tbl) => tbl.yourField.like('%substring%'))).watch();
}
Hope it will work. Thanks

Sequelize -- Use options.distinct with a Where Clause?

I'm trying to use Sequelize to find all distinct fields in a column, using a query with a where clause. I've searched the Sequelize docs and tried a number of different things, but haven't yet found the correct syntax.
Here's my current draft syntax:
var searchResults = connectors.cars.findAll({
attributes: [
connectors.Sequelize.options.distinct
],
where: {
condition: connectors.Sequelize.where(connectors.Sequelize.fn('LOWER', connectors.Sequelize.col('mfgr')), 'LIKE', '%' + searchString + '%')
}
});
What is the correct way to use options.distinct alongside a where clause?
Note: edited to remove a bunch of extra code that had been requested in the comments, but which in retrospect may have been obfuscating the issue.
Really more of a comment, but what's going on with this code?
}).then((searchResults) => searchResults.map((item) => item.dataValues));
debugger;
return searchResults; <== ERROR IS THROWN HERE
1) What is the destination of the map()? 2) Won't the return occur before the results are returned, as it's not in the .then() block? Should it not be more like this:
}).then((searchResults) => {
var new_results = searchResults.map((item) => item.dataValues));
debugger;
return new_results;
}
Am I missing something?
I'm getting the impression that this is hard to do in raw sql, let alone Sequelize. I found an answer that uses raw sql here:
const myQuery = "WITH cte AS\n" +
"( SELECT id, mfgr, ROW_NUMBER() OVER (PARTITION BY mfgr ORDER BY mfgr DESC) AS rn\n" +
" FROM cars\n" +
" WHERE LOWER(mfgr) like '%" + searchString + "%'\n" +
")\n" +
"SELECT *\n" +
"FROM cte\n" +
"WHERE rn = 1";
let searchResults = connectors.db.query(myQuery);

db.raw with more than one paremter with knex

This actually works in knex:
knex.raw('select * from users where id = ?', [1])
I am trying to use more than one value as parameters, repeating some of them. Something like this:
knex.raw('select * from users where id = 1? and name = 2? and firstName = 2?', [1, 'someName'])
How can I achieve that?
you can do something like this also:
var params = {x1:1,dude:10};
return knex.raw("select * from foo where x1 = :x1 and dude = :dude",params);
it's not the first example, but it's documented here.
It looks like the obvious quick solution is to simply repeat your array elements.
knex.raw('select * from users where id = 1? and name = 2? and firstName = 3?', [1, 'someName', 1])
I don't know knex, but there's nothing wrong with this solution either.
EDIT
A different approach is to use simple string interpolation through a library like kiwi:
var interpolateObject = {
id: 'some_id',
name: 'some_name',
firstName: 'some_first_name'
};
var query = Kiwi.compose(
"select * from users where id = %{id} and name = %{name} and firstName = %{firstName}",
interpolateObject
);
knex.raw(query);
Checkout kiwi.js

Creating Select statement with variable in single quotes

This relates to taking data from a Google Fusion table.
When I first set up my site, GF tableid was a numeric value, (var tableid = 123456;) and I built a query like this:
layer.setQuery("SELECT 'Latitude' FROM " + tableid + " WHERE 'Name' contains etc etc
Now tableid is something like var tableid = '12DFty24'; and I'm having trouble converting the setQuery to handle it.
I've tried adding an extra single quote around tableid, but that doesn't work. Nor do backslashes.
Ideas would be gratefully received!
Paul
You are using the old syntax that can't work with encrypted ID, numeric ID's are deprecated.
You have to change your code using the new syntax; here is the documentation
Example:
new google.maps.FusionTablesLayer({ query: {[FusionTablesQuery object]}});
And here's the one that works...need to be careful with parentheses and commas!
function searchAddress()
{
var searchString = document.getElementById('searchAddressString').value.replace("'", "\\'");
// layer.setQuery("SELECT 'Latitude' FROM " + tableid + " WHERE 'Address' contains ignoring case '" + searchString + "'");
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Latitude',
from: tableid,
where: 'Address' contains ignoring case '" + searchString + "'"
}
});
layer.setMap(map);
}