I'm working on aggregating my city's main big intersections with my city's collision data. What am trying to accomplish is to determine the number of accidents which happened in and around the intersection within a 20 meters radius.
Luckily, I'm already far off in the project and I have two tables in my database intersections and collisions
My intersections table:
--------------------------------------------
| id | city | Latitude | Longitude |
--------------------------------------------
| 1 | 1 | 34.44444 | 84.3434 |
--------------------------------------------
| 2 | 1 | 42.4666667 | 1.4666667 |
--------------------------------------------
| 3 | 1 | 32.534167 | 66.078056 |
--------------------------------------------
| 4 | 1 | 36.948889 | 66.328611 |
--------------------------------------------
| 5 | 1 | 35.088056 | 69.046389 |
--------------------------------------------
| 6 | 1 | 36.083056 | 69.0525 |
--------------------------------------------
| 7 | 1 | 31.015833 | 61.860278 |
--------------------------------------------
MY collisions table:
--------------------------------------------
| id | cause | Latitude | Longitude |
--------------------------------------------
| 1 | 1 | 44.44444 | 81.3434 |
--------------------------------------------
| 2 | 1 | 32.4666667 | 1.4666667 |
--------------------------------------------
| 3 | 1 | 42.534167 | 63.078056 |
--------------------------------------------
| 4 | 1 | 46.948889 | 62.328611 |
--------------------------------------------
| 5 | 1 | 45.088056 | 61.046389 |
--------------------------------------------
| 6 | 1 | 46.083056 | 63.0525 |
--------------------------------------------
| 7 | 1 | 41.015833 | 69.860278 |
--------------------------------------------
Note: Some fields were omitted for simplicity sake
As you can see, both tables posses latitude and longitude fields. Now to determine if intersection and collision coordinates are close, I thought of using a MySQL query that takes an id of an intersection which then queries the collisions table to get all collisions within 20 meters of the intersection.
What is this query (in MySQL or in Sequelize)?
Here's what I have now (it's in Sequelize using a MySQL database)
// api/collisions/{intersection_id}/count
exports.intersection_accident_count = (req, res) => {
intersection.findOne({where: {equipement: req.params.intersection_id}}).then(intersection => {
let intersectionLongitude = intersection.longitude;
let intersectionLatitude = intersection.latitude;
collision.count({where: {
longitude: {
$gt: intersectionLongitude
},
latitude: {
$gt: intersectionLatitude
},
}}).then(count => {
res.status(200).json({'number_of_accidents': count});
});
});
};
You should start with straightforward way:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_Distance_Sphere(POINT(i.Longitude, i.Latitude), POINT(c.Longitude, c.Latitude)) < #dist
)
This should give you results, however the query will not use any indexes at all and if you have many records it would be very slow.
You should think of adding geometry data types in your table:
ALTER TABLE `collisions` ADD COLUMN `Location` POINT;
UPDATE `collisions` SET Location = POINT(Longitude, Latitude);
ALTER TABLE `intersections` ADD COLUMN `Location` POINT;
UPDATE `intersections` SET Location = POINT(Longitude, Latitude);
You can add trigger so the Location will be populated automatically when you updating Longitude/Latitude.
Then:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_Distance_Sphere(i.Location, c.Location) < #dist
)
This would be a bit faster.
If you'd like to make it even faster, you can add another geometry poligon Area column into your intersection table and 'pre-build' areas (can be round for accuracy or square for speed).
After that you will be able to do something like this:
SELECT
i.*
FROM
intersections AS i
INNER JOIN collisions AS c ON (
ST_WITHIN(c.Location, i.Area)
)
Related
My dexiedb structure looks like below.
const db = new Dexie('shipment-execution');
db.version(1).stores({
root: '++id,shipmentid,stopid',
})
My IndexedDB will look like below
| id| shipmentid| stopid|
| 1 | 6000001 | 10 |
| 2 | 6000001 | 20 |
| 3 | 6000001 | 30 |
| 4 | 6000002 | 10 |
| 5 | 6000002 | 20 |
I am trying to get all the data which has shipmentid equal to 6000001. Each time it is returning only one record (the first record ).
db.root.where({shipmentid : '6000001'}).toArray().then((d)=>{
console.log(d);
})
output is only fetching the first record
| id| shipmentid| stopid|
| 1| 6000001 | 10 |
Please let me know, what I am doing wrong.
I got an array in Google Sheet that looks something like this :
+-----+---------+------------+------------+------------+-----+
| | A | B | C | D | ... |
+-----+---------+------------+------------+------------+-----+
| 0 | | Mission #1 | Mission #2 | Mission #3 | ... |
+-----+---------+------------+------------+------------+-----+
| 1 | Item #1 | 100 | 250 | 250 | ... |
+-----+---------+------------+------------+------------+-----+
| 2 | Item #2 | 200 | 1000 | 500 | ... |
+-----+---------+------------+------------+------------+-----+
| 3 | Item #3 | 300 | 3000 | 800 | ... |
+-----+---------+------------+------------+------------+-----+
| ... | ... | ... | ... | ... | ... |
+-----+---------+------------+------------+------------+-----+
I want to create a script that bold the highest value for each item. But there is a problem, as you can see, some items get the same value in different missions, what I need is in this case, only the "most right" needs to be bold.
So what I expect to do :
+-----+---------+------------+------------+------------+-----+
| | A | B | C | D | ... |
+-----+---------+------------+------------+------------+-----+
| 0 | | Mission #1 | Mission #2 | Mission #3 | ... |
+-----+---------+------------+------------+------------+-----+
| 1 | Item #1 | 100 | 250 | **250** | ... |
+-----+---------+------------+------------+------------+-----+
| 2 | Item #2 | 200 | **1000** | 500 | ... |
+-----+---------+------------+------------+------------+-----+
| 3 | Item #3 | 300 | **3000** | 800 | ... |
+-----+---------+------------+------------+------------+-----+
| ... | ... | ... | ... | ... | ... |
+-----+---------+------------+------------+------------+-----+
** = is bold
So I started to think :
var Item1High = max(b1;d1);
For each row (X1) if value == Item1High then set to bold
But at this state the most difficult part is to set in bold only the most right value (So the highest value of row)
And I'm stuck at this state.
Could you help me with that ?
I'm using Google Sheet Script in JavaScript.
Thanks !
You want to set the bold type to the maximum value in each row of Google Spreadsheet.
For example, when the column "B" and "C" is the same value and the maximum value, you want to set the bold to the column "C".
You want to achieve this using Google Apps Script.
The flow of this sample script is as follows.
Flow:
Retrieve all values from the sheet.
Create text styles.
Set the created text styles.
Sample script:
Before you run the script, please set the sheet name.
function myFunction() {
const sheetName = "Sheet1";
// 1. Retrieve all values from the sheet.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const range = sheet.getDataRange();
const values = range.getValues();
values.shift();
// 2. Create text styles.
const tempStyle = SpreadsheetApp.newTextStyle().setBold(false).build();
const bold = SpreadsheetApp.newTextStyle().setBold(true).build();
const styles = values.map(r => {
r.shift();
let ar = Array(r.length).fill(tempStyle);
ar[r.lastIndexOf(Math.max(...r))] = bold;
return ar;
});
// 3. Set the created text styles.
range.offset(1, 1, styles.length, styles[0].length).setTextStyles(styles);
}
References:
newTextStyle()
setTextStyles()
Added:
In this sample script, the selected range is used.
function myFunction() {
const sheetName = "Sheet1";
const selectRange = "B2:D4"; // Please set the range you want to use.
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
const tempStyle = SpreadsheetApp.newTextStyle().setBold(false).build();
const bold = SpreadsheetApp.newTextStyle().setBold(true).build();
const range = sheet.getRange(selectRange);
const values = range.getValues();
const styles = values.map(r => {
let ar = Array(r.length).fill(tempStyle);
ar[r.lastIndexOf(Math.max(...r))] = bold;
return ar;
});
range.setTextStyles(styles);
}
I have the following table:
+----------+----------+---------+----------+----------+----------+
| Date | A | B | C | P | D |
+----------+----------+---------+----------+----------+----------+
|2019-01-10| -111,000 | 666,000 | 78,000 | 45 | 120,000 |
|2019-01-09| 555,000 | 55,000 | 100,000 | 55 | 700,000 |
|2019-01-08| 48,000 | 30,000 | 40,000 | 65 | 450,000 |
|2019-01-07| 600,000 |-450,000 | -800,000 | 90 | 980,000 |
+----------+----------+---------+----------+----------+----------+
May I know how to create a temporary table from the existing table above to become the table as below:
+----------+----------+---------+----------+----------+
| Date |Components| Values | Comp_no | P |
+----------+----------+---------+----------+----------+
|2019-01-10| A |-111,000 | 1 | 45 |
|2019-01-10| B | 666,000 | 2 | 45 |
|2019-01-10| C | 78,000 | 3 | 45 |
+----------+----------+---------+----------+----------+
Then sort it according to absolute values as below:
Give numbers to the largest value as '1', 2nd largest as '2' and so on.
The sorted_comp_no represents the order whereby the components is sorted where '1' is 'B', '2' is A and '3' is C.
+----------+----------+---------+----------+----------+--------------+
| Date |Components| Values | comp_no | P | sort_sequence|
+----------+----------+---------+----------+----------+--------------+
|2019-01-10| A |-111,000 | 1 | 45 | 2 |
|2019-01-10| B | 666,000 | 2 | 45 | 1 |
|2019-01-10| C | 78,000 | 3 | 45 | 3 |
+----------+----------+---------+----------+----------+--------------+
Use the comp_no and sort.
The components are now sorted according to their values.
+----------+----------+---------+----------+----------+--------------+
| Date |Components| Values | comp_no | P |sorted_comp_no|
+----------+----------+---------+----------+----------+--------------+
|2019-01-10| B | 666,000 | 2 | 45 | 2 |
|2019-01-10| A |-111,000 | 1 | 45 | 1 |
|2019-01-10| C | 78,000 | 3 | 45 | 3 |
+----------+----------+---------+----------+----------+--------------+
I've already created the temporary table template but still stuck in taking the name of specific column only (A,B and C) to be put into a column of its own category ignoring column D . Column P is brought into the temporary table but remain as is. There is also a dependency to the date column as there are multiple data of different date.
But the end goal is to be able to "sort specific column according to its absolute value at a specific date dynamically".
I have a SQLite Table:
+---------+-----------+-----------+-----------+
| userID | balance | ledger | lasttopup |
+---------+-----------+-----------+-----------+
| 1 | 90 | 780 | 12/10/18 |
| 2 | 180 | 0 | 4/11/18 |
| 3 | 270 | 12 | 13/10/18 |
| 4 | 360 | 109 | 11/10/18 |
+---------+-----------+-----------+-----------+
And I am accessing the column ledger via:
const conn = new require('better-sqlite3')('../../data/databases/casino.sqlite3');
const balances = conn.prepare(`SELECT * FROM "${msg.guild.id}"`).all().map(e => e.ledger)
And I want to get the userID which pertains to the respective ledger entry.
Visual:
Visualization
And then perform an action on the ledger value.
But I am unsure of how to retrieve the userID.
Any help will we appreciated!
[LIBRARIES]
DiscordJS
better-sqlite3
~Thanks
I have a working event tracker that writes every event in a mysql table.
Table
id date userid event
5100 2014-03-25 14:18:55 user333 AI
5101 2014-03-25 14:19:02 user333 Click
5102 2014-03-25 14:19:02 user333 Click
...
Thats works so far very good. But now, I want to write a little report tool in node.js
I try to get the values with this SQL Query:
SELECT DATE_FORMAT(date,"%Y%m%d") AS date, event, count(*) AS count FROM databasetest WHERE date>="'+ daystartdate +'" AND date<="'+ dayenddate +'" GROUP BY YEAR(date), MONTH(date), DAY(date), event
Giving me this:
+----------+----------+-------+
| date | event | count |
+----------+----------+-------+
| 20140320 | AI | 6 |
| 20140320 | Click | 2 |
| 20140320 | swipe | 2 |
| 20140321 | Click | 6 |
| 20140321 | error | 5 |
| 20140321 | swipe | 2 |
| 20140321 | touch | 3 |
| 20140322 | AI | 3 |
| 20140322 | Click | 3 |
| 20140322 | error | 1 |
| 20140322 | mapsload | 3 |
| 20140322 | touch | 1 |
| 20140323 | AI | 2 |
| 20140323 | Click | 2 |
| 20140323 | touch | 5 |
| 20140324 | AI | 3 |
| 20140324 | Click | 1 |
| 20140325 | AI | 25 |
| 20140325 | Click | 48 |
| 20140325 | error | 16 |
| 20140325 | mapsload | 7 |
| 20140325 | swipe | 15 |
| 20140325 | touch | 32 |
+----------+----------+-------+
But I need the data in this form:
+----------+----------+-------+-----
| date | Click | AI | ....
+----------+----------+-------+-----
| 20140320 | 0 | 6 |
| 20140321 | 2 | 2 |
| 20140321 | 2 | 5 |
Is this possible with a SQL query or do I need to loop through the results in my javascript code. I tried many possible solution but didnt get it to work.
Thank you.
This is a very common question, keywords to search are "transpose" and "pivot". To save you the trouble, this is something that MySQL is not able to do. SQL Server (a MS product) can do this, though.
You will need to loop through the output and build the result set yourself.
var results = []
data.forEach(function(row, rowidx) {
results[row.date] = results[row.date] || {};
results[row.date][row.event] = results[row.date][row.event] || 0;
results[row.date][row.event] += row.count;
});