finding the documents containing a value closest to int - javascript

Im having the following schema:
var lottary = new Schema({
userid : String,
start: Number,
end: Number,
time: Number,
});
and im writing a query that get the result of the winner.
if the rows are as follows:
| start | end |
| 2 | 4 |
| 5 | 99 |
| 100 | 999 |
and my number are 55, it would return the row with start 5, and end 99, cause 55 is between those numbers.
I know this are done with the following in MYSQL:
SELECT *
FROM lotto_tickets
WHERE 40 BETWEEN start AND end
But, how is this done within mongoose / mongodb?

Possible duplicate, take a look at this: How to find documents having a query-value within the range of two key-values
db.lottary.find({ "start": { "$lt": 55}, "end": { "$gt": 55}});
You can obviously change the number 55 to anything u want.

Related

How to get substring dynamically

How can I get substring dynamically, I want to split one word into two parts one is a string and other to no,
AA112 this is my string so from sql query
SELECT substr(thisColumn, 1,2) AS String from thisTable
I am getting AA in the query the index(2) I am pasing is dynamic I am getting from some value, So here I am able to get the string now I want to get the number +1 like it is 112 then -> 113
I have tried several queries but it is not working, I have tried doing it with javascript substring but it didn't work out.
Sample output
AAA123 -> AAA and 124
AA4 -> AA and 5
BBBB8 -> BBBB and 9
const input="AA112";
var numberPattern = /\d+/g;
const number = input.match(numberPattern)[0];
const text = input.replace(number,"");
console.log(text); //AA
console.log(number); //112
const incremented = parseInt(number) + 1;
console.log(incremented);
Using LOCATE, IF,LEAST and SUBSTRING over two sub-query can achieve the output result you're looking for.
SELECT VAL,
SUBSTRING(VAL,1,FIRSTNUM-1),
SUBSTRING(VAL,FIRSTNUM,999)+1
FROM
(SELECT VAL,LEAST(V0+0,V1+0,V2+0,V3+0,V4+0,V5+0,V6+0,V7+0,V8+0,V9+0) FIRSTNUM FROM
(SELECT VAL,
IF(LOCATE(0,VAL)=0,999,LOCATE(0,VAL)) V0,
IF(LOCATE(1,VAL)=0,999,LOCATE(1,VAL)) V1,
IF(LOCATE(2,VAL)=0,999,LOCATE(2,VAL)) V2,
IF(LOCATE(3,VAL)=0,999,LOCATE(3,VAL)) V3,
IF(LOCATE(4,VAL)=0,999,LOCATE(4,VAL)) V4,
IF(LOCATE(5,VAL)=0,999,LOCATE(5,VAL)) V5,
IF(LOCATE(6,VAL)=0,999,LOCATE(6,VAL)) V6,
IF(LOCATE(7,VAL)=0,999,LOCATE(7,VAL)) V7,
IF(LOCATE(8,VAL)=0,999,LOCATE(8,VAL)) V8,
IF(LOCATE(9,VAL)=0,999,LOCATE(9,VAL)) V9 FROM mytable) A ) B;
Here I use LOCATE to find the location of the number occurrence in the value then REPLACE to change the value to 999 if it returns 0. This is essential for the next operation using LEAST because if I leave it 0, it'll return all 0 instead. The reason I use LEAST is because if you look at the 4th data example in the fiddle it's AAAAA321. This will return the result in grid like the following:
+----------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| VAL | V0 | V1 | V2 | V3 | V4 | V5 | V6 | V7 | V8 | V9 |
+----------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
| AAA123 | 999 | 4 | 5 | 6 | 999 | 999 | 999 | 999 | 999 | 999 |
| AA4 | 999 | 999 | 999 | 999 | 3 | 999 | 999 | 999 | 999 | 999 |
| BBBB8 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 999 | 5 | 999 |
| AAAAA321 | 999 | 8 | 7 | 6 | 999 | 999 | 999 | 999 | 999 | 999 | <---this
| AAA45 | 999 | 999 | 999 | 999 | 4 | 5 | 999 | 999 | 999 | 999 |
+----------+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+
The first number occurrence is actually '3' but because I construct the query running from 0-9, I'll always get the first number in front (in this case '1' is the 8th occurrence) despite it being on the middle or last position. That's why LEAST will correctly take which number is actually located first using LOCATE function.
In the last outer query, I use the result from the LEAST function (assigned as FIRSTNUM) as the defining value for the SUBSTRING. The first substring I use it as the end location subtract by 1 to get the strings and in the second substring I use it as the first location to get the number (I end the location with 999).
Fiddle: https://www.db-fiddle.com/f/F15cxiYJxGcozYUbQukeB/5
Edit: I realized I cannot use REPLACE because if the location is like 10, it will replace 0 to 999 which makes it become 1999 instead. So I use IF.

MySQL select all values which share this field's value

I am new to MySQL so describing problems in words is difficult and searching for solutions is extremely challenging.
This problem is best explained visually:
I want to select (as an array) exchange_pair_id's that share the same pair_id.
So in the above data, my MySQL query would return an object:
{ pair_id: 1, exchange_pair_id: [183, 1] }
I am aware this is a butchered question, but I do not know the words to search to solve this problem.
Updated for clarity/brevity:
+------------------+-------------+---------+
| exchange_pair_id | exchange_id | pair_id |
+------------------+-------------+---------+
| 1 | 3 | 1 |
+------------------+-------------+---------+
| 183 | 1 | 1 |
+------------------+-------------+---------+
| 69 | 2 | 2 |
+------------------+-------------+---------+
| 12 | 4 | 2 |
+------------------+-------------+---------+
| 2 | 3 | 2 |
+------------------+-------------+---------+
| 3 | 3 | 3 |
+------------------+-------------+---------+
Desired output from a Javascript MySQL select query:
[
{ pair_id: 1, exchange_pair_id: [1, 183] },
{ pair_id: 2, exchange_pair_id: [69, 12, 2] },
{ pair_id: 3, exchange_pair_id: [3] }
]
I am thinking a query like this , but I'm waiting your answer at comments.
Basically, you use GROUP BY to obtain in two different columns the values for each pair_id:
SELECT pair_id, MIN(exhange_pair_id) AS id1, MAX(exchange_pair_id) AS id2
FROM yourtable
GROUP BY pair_id;
Update version: Can you try this please on your data?
In this case MYSQL let you concat field using a separator (,)
SELECT pair_id, GROUP_CONCAT(exhange_pair_id) AS exhange_pair_id
FROM yourtable
GROUP BY pair_id
try select exchange_pair_id from yourtable where pair_id=1 then it will return array [1,183]
The SQL you are looking for would be:
SELECT * WHERE pair_id == 1
Without knowing what your specific code looks like, I can only guess as to how you are implementing a call to your database. I would assume you are doing some sort of async call to a PHP controller. So instead of using '1' in the query, you will need to use whatever variable you are pulling from your code to know what you are looking for.

Node combined multiple rows into one using mysql or lodash

Currently, I'm using Node MySQL library to implement MySQL query in Javascript framework. I have an issue about the left join with multiple rows. When I left join that table, it returns more than one object, this is because the left join will produce duplicate rows but different values of that particular attribute. What I want to achieve right now is, returns one object and insert that multiple values to array of that particular attribute.
Table A
id | name | age
1 abel 22
2 john 22
Table B
id | user_id | equip
1 1 armor
2 2 sword
3 1 knife
4 2 gun
Query
SELECT * FROM Table_A LEFT JOIN TABLE_B ON TABLE_B.user_id = TABLE_A.id;
Current Situation
{
id: 1
name: abel
age: 22
user_id: 1
equip: 'armor'
},
{
id: 1
name: abel
age: 22
user_id: 1
equip: 'knife'
},
{
id: 2
name: john
age: 22
user_id: 2
equip: 'sword'
},
{
id: 2
name: john
age: 22
user_id: 2
equip: 'gun'
}
What I want to achieve
{
id: 1
name: abel
age: 22
user_id: 1
equip: [
'armor','knife'
]
},
{
id: 2
name: john
age: 22
user_id: 2
equip: [
'sword','gun'
]
}
Anyway to achieve using node mysql query or lodash?
What you're trying to do can't be accomplished with a join. Here's what I came up with, though SQL wizards may have better solutions:
SELECT Table_A.name, GROUP_CONCAT(item_name) AS equip
FROM Table_B
JOIN Table_A
ON Table_A.id=Table_B.person_id
WHERE Table_A.id=1;
That will produce
+------+-------------------+
| name | person_items |
+------+-------------------+
| abel | armor,sword,knife |
+------+-------------------+
Then just create an array with split(','). But I see a few problems beyond the one you're trying to solve.
Table_B is doing too much work. Drop the user_id column and create a third table, Table_A_Table_B, with three columns: id primary key, table_a_id foreign key referring to Table_A.id; table_b_id foreign key referring to Table_B.id.
Unless you change the tables this way, you'll need to enter an item name every time you add a row to Table B. Eliminate that redundancy, and use the relational database properly, by creating/inserting the item once in its own table and using a child table to point to it and an entity in Table_A whenever you need to connect them (that's Table_A_Table_B).
Names need to be more descriptive and accurate, ex. Table_A -> people, Table_B -> items, and Table_A_Table_B -> 'person_item,equip->item_name`.
From square one:
CREATE TABLE people (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT UNSIGNED
);
CREATE TABLE items (
id INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
item_name VARCHAR(20)
);
CREATE TABLE person_item (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
person_id INT UNSIGNED NOT NULL,
item_id INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (person_id)
REFERENCES people(id)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (item_id)
REFERENCES items(id)
ON UPDATE CASCADE ON DELETE CASCADE
);
Mix in a bit of data:
INSERT INTO people (name, age) VALUES ('abel', 20), ('john', 21);
INSERT INTO items (item_name) VALUES ('armor'), ('sword'), ('knife');
INSERT INTO person_item (person_id, item_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3);
MySQL doesn't support arrays, and best practices for what you want to do would, I think, be not to do it at all, but instead to do this:
SELECT p.*, i.*
FROM people p
JOIN person_item pi
ON p.id=pi.person_id
JOIN items i
ON i.id=pi.item_id
WHERE p.id=1;
which would produce:
+------+-----+-----------+
| name | age | item_name |
+------+-----+-----------+
| abel | 22 | armor |
| abel | 22 | sword |
| abel | 22 | knife |
+------+-----+-----------+
which you could then use Node to get the data you want. Or you can do this:
SET sql_mode='';
SELECT people.name, GROUP_CONCAT(item_name) AS person_items
FROM items
JOIN person_item
ON person_item.item_id=items.id
JOIN people
ON people.id=person_item.person_id
WHERE people.id=1;
Producing:
+------+-------------------+
| name | person_items |
+------+-------------------+
| abel | armor,sword,knife |
+------+-------------------+

What does the expression `p[i&1]+=v,p` mean?

I was practicing my javascript with CodeFights and after I finished an exercise I saw this function as a result:
// Subject :
// Several people are standing in a row and need to be divided into two teams.
// The first person goes into team 1, the second goes into team 2,
// the third goes into team 1 again, the fourth into team 2, and so on.
// You are given an array of positive integers - the weights of the people.
// Return an array of two integers, where the first element is the total weight of
// team 1, and the second element is the total weight of team 2
// after the division is complete.
// Example :
// For a = [50, 60, 60, 45, 70], the output should be
// alternatingSums(a) = [180, 105].
// answer
alternatingSums = a => a.reduce((p,v,i) => (p[i&1]+=v,p), [0,0])
I don't understand what p[i&1]+=v,p means.
The & symbol is a bitwise binary operator.
To understand what would happen, you have to convert each item to binary.
| i (decimal) | i (binary) | i & 1 |
|-------------|------------|-------|
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 2 | 10 | 0 |
| 3 | 11 | 1 |
| 4 | 100 | 0 |
| 5 | 101 | 1 |
Effectively, every even number will be transformed to 0, and every odd number will be transformed to 1.
If I was trying to achieve that outcome, I personally would have used the modulus operator (%)
p[i%2] += v;
But that's just me.
The other part is that there are two statements separated by a comma:
(p[i&1]+=v,p)
That's saying "Perform this action, then return p. It's shorthand for:
alternatingSums = a => a.reduce((p,v,i) => {
p[i&1]+=v;
return p;
},
[0,0])
It looks for an element of the p array that has index of i&1 - it is a bitwise AND operation. Then, increments its value by a value of v variable. Finally, returns the value of p variable.

Creating a nested JSON object from SQL results

I'm trying to figure out how to create a nested JSON object, something like this:
company: "Company 1",
pricing: {
term: "1 year",
price: "$4.95",
term: "2 years",
price: "3.95"
},
I have two tables in MySQL, one called plans which is structured in this fashion
| id | company |
------------------
| 2 | company 1 |
and another table plans_pricing to represent the pricing data
| id | plans_id | term | price |
--------------------------------
| 1 | 2 | 1 year | $4.95 |
| 2 | 2 | 2 years| $3.95 |
I am using Laravel 4 to query the database and create json to send back to my ajax request. Here is the query, which is currently sending a server 500 error.
public function results()
{
$answers = $_POST['answers'];
$data = DB::table('plans')
->join('plans_pricing', 'plans.id', '=', 'plans_pricing.plans_id')
->select('plans.company', 'plans_pricing.price', 'plans_pricing.term')
->whereIn('plans.id', $answers)
->get();
echo json_encode($data);
}
I'm not sure why this query isn't working, but that isn't even why i'm asking this question. I need to know how to get a nested JSON object, when I create the join, I believe that I'll receive a separate object for each, like here:
| company | price | term |
------------------------------------
| company 1 | 4.95 | 1 year |
| company 1 | 3.95 | 2 years|
How can I make this SQL query return a nested JSON object like the one I describe above? I have been stuck on this problem for two days now and could really use some guidance. Thanks
UPDATE:
The server 500 error was fixed by changing echo json_encode to return Response::json($data);
I've never used Laravel but I think this should work:
$output = array();
$currentCompany = "";
foreach ($data as $datum) {
if ($datum->company != $currentCompany) {
$output[] = array();
// get a reference to the newly added array element
end($output);
$currentItem = & $output[key($output)];
$currentCompany = $datum->company;
$currentItem['company'] = $currentCompany;
$currentItem['rates'] = array();
}
$currentItem['rates'][] = array("price" => $datum->price, "term" => $datum->term);
}
json_encoded result:
[{
"company":"company 1",
"rates":[{
"price":4.95,"term":"1 year"
},{
"price":3.95,"term":"2 years"
}]
}]

Categories

Resources