How can I access column's from SELECT, in my WHERE statement? I'm probably missing quotes. For context, this is in a controller, in Strapi CMS, which runs on a node.js server.
Problem:
Occurs at AND statement (mainly the first st_geomfromtext line):
const rawBuilder = strapi.connections.default.raw(
`
SELECT
locations.id as Location_ID,
locations.Title as Location_Title,
locations.Latitude as Location_Latitude,
locations.Longitude as Location_Longitude,
things.id,
things.Title,
things.Location
FROM locations
RIGHT JOIN things
ON locations.id = things.Location
WHERE things.Style = ` + ctx.query['Style.id'] + `
AND round(st_distance_sphere(
st_geomfromtext(CONCAT('POINT(',locations.Longitude, ' ', locations.Latitude,')')),
st_geomfromtext(CONCAT('POINT(` + ctx.query.Longitude + ` ` + ctx.query.Latitude + `)'))
)) <= ` + 5000
)
Test works:
Just for fun, same as above, but just passed request variables for both st_geomfromtext lines, and the response works; no SQL error:
AND round(st_distance_sphere(
st_geomfromtext(CONCAT('POINT(` + ctx.query.Longitude1 + ` ` + ctx.query.Latitude1 + `)')),
st_geomfromtext(CONCAT('POINT(` + ctx.query.Longitude2 + ` ` + ctx.query.Latitude2 + `)'))
)) <= ` + 5000
So as far as I can tell, the first st_geomfromtext line is the culprit, however it (the 1st line) works fine in a Go server... another clue that this is just a syntax problem.
Below is a working example in SQL Server that should help you resolve this.
Please try these steps:
Remove the "AND" statement from your where clause and save it somewhere
Add some filter criteria that will give you just few known locations
Add new output fields in your select criteria for each function so you will know what you are comparing.
Select CONCAT('POINT(',locations.Longitude, ' ', locations.Latitude,')') from locations
Select st_geomfromtext(CONCAT('POINT(',locations.Longitude, ' ', locations.Latitude,')')) from locations
Note: the output to the geo functions this will probably look cryptic like 0xE6100000010C75931804564253C042CF66D5E7724340
Once the values line up the way you expect then add a new version of the where clause with the adjustments you have made.
Check the precision of the st_distance_sphere function. In SQL Server this is defaulted to meters.
Example in SQL Server
CREATE TABLE #locations (id INT, Title VARCHAR(50), Latitude DECIMAL(10,4), Longitude DECIMAL(10,4))
CREATE TABLE #things (id INT, Title VARCHAR(50), LocationId INT)
INSERT INTO #locations (id, Title, Latitude, Longitude) Values (1,'WH', 38.8977, -77.0365)
INSERT INTO #locations (id, Title, Latitude, Longitude) Values (2,'CB', 38.8899, -77.0091)
INSERT INTO #things (id, Title, LocationId) Values (100,'White House',1)
INSERT INTO #things (id, Title, LocationId) Values (101,'United States Capitol',2)
--My Location at the Washington Monument
DECLARE #myLat DECIMAL(10,4) = 38.8895;
DECLARE #myLong DECIMAL(10,4) = -77.0353
SELECT
loc.id as Location_ID,
loc.Title as Location_Title,
loc.Latitude as Location_Latitude,
loc.Longitude as Location_Longitude,
th.id,
th.Title,
th.LocationId,
geometry::STGeomFromText(CONCAT('POINT(',loc.Longitude, ' ', loc.Latitude,')'),4326) as ItemPoint,
geometry::STGeomFromText(CONCAT('POINT(',#myLat,' ',#myLong,')'),4326) as MyPoint,
geometry::STGeomFromText(CONCAT('POINT(',loc.Longitude, ' ', loc.Latitude,')'),4326).STDistance(geometry::STGeomFromText(CONCAT('POINT(',#myLat,' ',#myLong,')'),4326))
FROM #locations loc
RIGHT JOIN #things th ON loc.id = th.LocationId
DROP TABLE #locations
DROP TABLE #things
I want to insert bunch of records into a collection, but instead of document at a time I want to do it like a batch using "insertMany()". I wrote the script as follows:
var batch = [];
for (i=0; i<10; i++) {
names=["exam", "essay", "quiz"];
for (j=0;j<3;j++) {
batch += '\n{ student : ' + i + ', type : "' + names[j] + '", score : ' + Math.round(Math.random()*100) + '}' ;
if (mod i%3 == 0) {
batch = batch.slice(0, batch.lenght(-1));
db.scores.insertMany( batch )
batch=[];
}
}
}
The above code is not working. There are two issues: first, the array item have double quotes around them and second, the "slice" is not taking effect.
Need help in fixing the Javascript.
There are a couple of issues here:
the array item have double quotes around them
batch += '\n{ student : ' + i + ', type : "' + names[j] + '", score : ' + Math.round(Math.random()*100) + '}' ;
You want to create an object rather than a string. batch = { student: i, type: names[j], score: ..} will create an object for you.
the "slice" is not taking effect
batch = batch.slice(0, batch.lenght(-1));
You've misspelled length, and length is a property rather than a function. batch.slice() will copy the array (but you're resetting it so it's not actually necessary).
I have a very basic question:
SELECT name, surname CONCAT(name, surname) AS name_surname from users;
How can I convert this SQL to MongoDB query?
During my search, I have decided that it is possible with aggregate framework due to concat, but what I received is only projection of concat(name, surname) not name, surname and concat(name, surname).
Final thing I got is this query:
db.inroamers.find().forEach(
function(o) {
print(o.LAC + '-' + o.CELL + ' ' + o.CHARGE + ' ' + o.WEEK);
})
but it does not give me proper json array.
Any suggestions?
Use the aggregation operations as below:
db.collection.aggregate([
{$project:{"name_surname":{$concat:["$name","-","$surname"]},"name":1,"surname":1}}
])
So i'm using multiple if statements to draw data from a database based on the users search criteria.
What i'm struggling with is
if(request.getParameter("searchProperty")!= ""){
SearchStatement = "town_city = '" + request.getParameter("searchProperty") + "'";
if(request.getParameter("bedrooms") != "0"){
SearchStatement += " AND bedrooms = '" + request.getParameter("bedrooms") + "'";
}
}
with the idea that this concatenates a string to use as a query in the database, and bring back the results the user is searching for (this is a property searching website). I thought i'd done the if statement correctly. From what i understand, from what i've put, if the user were to select 0 in bedrooms it should return ALL results, but instead it returns NONE (who wants a house without a bedroom..) Can somebody explain what's going wrong please?
here's where the SQL statement is built and input
MyProperties = bookSQL.executeQuery("SELECT * FROM PROPERTIES WHERE " + SearchStatement);
with the expected outcome being, for example
SELECT * FROM PROPERTIES WHERE Location = 'input' AND Bedrooms = 'value'
unless value = 0 where it should just be
SELECT * FROM PROPERTIES WHERE Location = 'input'
i think the problem is with this statement,
request.getParameter("bedrooms") != "0"
should be something like this ,
(!request.getParameter("bedrooms").isEmpty())
Remember you are comparing the strings
so if is "0"
if(request.getParameter("bedrooms").equals("0")){
return SearchStatement ;
}
else {
SearchStatement += " AND bedrooms = '" + request.getParameter("bedrooms") + "'"
}
Hope this helps!!
I have a string that has a query.
The problem is I cannot just append to it, after the where clause there is a group by.
So say i'm given this string:
var query = "select stuff from db where something = 3 group by stuff"
Now I want to append "somethingelse > 5 AND "
Result:
query = "select stuff from db where somethingelse > 5 AND something = 3 group by stuff"
What do I need to do to do this? Thanks
query = query.replace(/where/,'where somethingelse > 5 AND');
David's answer is the most pragmatic if you are passed the query string as-is.
Alternatively, if you're building it up yourself it may be better to allow the list of selectors, query constraints etc. to be passed in so that you create a correct query string initially. Something a bit like:
val query = "select " + selectors.join() +
" from " + tables.join() +
" where " + constraints.join() +
" group by " + groupings.join()