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"
}]
}]
Related
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.
Simply I'm trying to make it ignore sorting if the cell has ?
this is my table:
ID | name | supply
1 | John | 12
2 | Kayle | ?
3 | Tim | 24
when you sort supply by asc
ID | name | supply
1 | John | 12
3 | Tim | 24
2 | Kayle | ?
when you sort supply by desc
ID | name | supply
3 | Tim | 24
1 | John | 12
2 | Kayle | ?
IS there a way to do it?
You need to use Absolute position sorting plug-in.
For example:
var nameType = $.fn.dataTable.absoluteOrder({
value: '?', position: 'bottom'
});
var table = $('#example').DataTable({
columnDefs: [
{ targets: 0, type: nameType }
]
});
You need to include absolute.js file in addition to DataTables CSS/JS files.
See this example for code and demonstration.
I need to display data like below
+------+----------+----------+----------+
| Name | Subject1 | Subject2 | subject3 |
+------+----------+----------+----------+
| A | 20 | 30 | 40 |
| B | 21 | 31 | 41 |
| C | 2 | 3 | 4 |
+------+----------+----------+----------+
I used spring mvc. I created a model - Student.Java
import java.util.ArrayList;
public class Student {
ArrayList<String> markList;
public ArrayList<String> getMarkList() {
return markList;
}
public void setMarkList(ArrayList<String> markList) {
this.markList = markList;
}
}
I used ResponseBody and returned List for that method. I used ajax call and got the JSON response as below
[{"markList":["name","subject1","subject2","subject3"]}{"markList": ["A",20","30","40"]},{"students":["B",21","31","41"]},{"students":["C",2","3","4"]}]
In my Angularjs controller i just used a ajax call and assigned as below
var reponseData= reponse.data;
var studentarray;
var marklist;
for(var i=0;i<responseData.length;i++){
studentarray.push(responseData[i]);
}
for(var j=0;j<studentarray.length;j++){
marklist.push(studentarray[j].markList);
}
$scope.studentslist=marklist;
My jsp code
{{col}}
But I am not getting the desired result.Can somebody help me how to design the model and access it in js. Please help
You don't need to re-iterate an array an create a new array on the page, just directly assigns response.data to studentslist. You could just use ng-repeat to render a table on page.
<table class="table table-bordered">
<tr ng-repeat="list in studentslist">
<td ng-repeat="mark in list.markList">{{mark}}</td>
</tr>
</table>
I have Table (Employees) A:
+----+---------+
| ID | NAME |
+----+---------+
| 1 | ROBERT |
| 2 | JAMES |
| 3 | RICHARD |
| 4 | KANYE |
| 5 | DYLAN |
| 6 | JOHN |
| 7 | JEAN |
| 8 | LOKI |
| 9 | ADAM |
+----+---------+
And Table (Employees) B:
+----+---------+
| ID | NAME |
+----+---------+
| 1 | ROBERT |
| 2 | JAMES |
| 3 | RICHARD |
| 4 | KANYE |
| 5 | DYLAN |
+----+---------+
Those people are my "employees". The names from table B are all the employees on my database and the names from table A are all the employees that I've assigned to project n°1.
I would like to HIDE all names in Table B that already appear in Table A because I don't want to re-assign the same employee to project n°1.
How can I resolve this using jQuery?
a clientside check would be:
function compareLists(listA, listB){
var resultList = [];
listA.forEach(function(itemA){
listB.forEach(function(itemB){
if (itemB.name !== itemA.name)resultList.push(itemB);
}
}
return resultList;
}
or at the serverside (database):
select * from table_b where name not in (select name from table_a)
greetings
Normally you should do that on the server side using SQL as already answered. However, since you ask about javascript. This is the way to filter it at client side:
//collect list of names in A
var table = document.getElementById("TableA");
var names = []
for (var i = 0, row; row = table.rows[i]; i++) {
names.push(row.celss[1]);
}
//check names in B
table = document.getElementById("TableB");
for (var i = 0, row; row = table.rows[i]; i++) {
if(jQuery.inArray(row.cells[1], names) !== -1){
//show row
}else{
//hide row
}
}
I dont have that much knowlwdge in Jquery..
But this query increases perfomance in a large DB.
SELECT
FROM TableB
LEFT JOIN TableA ON TableB.name=TableA.name // id will be better than name
WHERE TableB.name IS NULL
Hope this helps
I have a Javascript program that is querying a MySQL table and I can't figure out why the results of simultaneous queries are not well handled.
There are multiple instances of an object, Zone. When instanciating the objects, I query the database to get some info.
My problem is that when I instanciate two objects at the same time, the result of the query of the first one is written in the second object.
I tried to create two different connections using a pool, but it doesn't change anything.
Here is my code :
Getter into database :
getOrdresAchat = function(aConnection, aIdZone, aCallback){
aConnection.query("SELECT * FROM Ordre WHERE Entreprise_idEntreprise = "+aIdZone+" AND Sens = 'Achat' ORDER BY Valeur DESC;", aCallback);
}
Objects definition :
//No need to check that object
Ordre = function(aNumero, aJoueur, aEntreprise, aSens, aTypeOrdre, aQuantite, aPrix, aBorneInf, aBorneSup) {
this.numero = aNumero;
this.entreprise = aEntreprise;
this.joueur = aJoueur;
this.sens = aSens;
this.typeOrdre = aTypeOrdre; // 'cours_limite', 'meilleure_limite', 'seuil_declenchement' ou 'au_marche'
this.quantite = aQuantite; // nombre entier positif
this.prix = aPrix; //si le prix est nul il est considéré comme sans limite
this.borneInf = aBorneInf;
this.borneSup = aBorneSup;
}
//kinda an array of Ordre
Carnet_achat = function() {
this.liste = [];
this.addElement = function(aOrdre) {
this.liste.push(aOrdre);
};
this.display= function(){
console.log("begining carnet_achat.display | List.length : "+this.liste.length);
for(i in this.liste){
console.log("row "+i+" : " +this.liste[i].prix);
}
};
}
Zone = function(aIdZone, aConnection) {
var idZone = aIdZone;
this.setIdZone = function(aNewId){
idZone = aNewId;
}
this.getIdZone =function(){
return idZone;
}
this.getCarnetAchat = function(aConnection){
rCarnet_achat = new Carnet_achat(); //rCarnet is temporary object
//we query database and push every row into the temp object
getOrdresAchat(aConnection, idZone, function(err, rows){
if(err) throw err;
for(i in rows){
ordreToAdd = new Ordre(rows[i].idOrdre,
rows[i].Joueur_idJoueur,
rows[i].Entreprise_idEntreprise,
rows[i].Sens,
rows[i].Type,
rows[i].Quantite,
rows[i].Valeur,
rows[i].BorneInf,
rows[i].BorneSup);
rCarnet_achat.addElement(ordreToAdd);
}
});
return rCarnet_achat;
}
//init
this.carnet_achat = new this.getCarnetAchat(aConnection);
}
main :
var mysql = require('mysql');
var pool = mysql.createPool({
host : 'localhost',
user : 'Bibacoeur',
password : 'Bibacoeur2014',
database : 'bibacoeur'
});
pool.getConnection(function(err, connectionA) {
if(err) throw err;
GI = new Zone(1, connectionA); //connection is used to query database
//timeOut to wait the end of the query
setTimeout(function(){console.log("GI_ACHAT");GI.carnet_achat.display();},3000);
});
pool.getConnection(function(err, connectionB) {
if(err) throw err;
GE = new Zone(2, connectionB); //connection is used to query database
//timeOut to wait the end of the query
setTimeout(function(){console.log("GE_ACHAT");GE.carnet_achat.display();},3000);
});
DATABASE :
mysql> select Entreprise_idEntreprise, Sens, Valeur from ordre;
+-------------------------+-------+--------+
| Entreprise_idEntreprise | Sens | Valeur |
+-------------------------+-------+--------+
| 1 | Vente | 0 |
| 1 | Vente | 90000 |
| 1 | Vente | 91000 |
| 1 | Vente | 92000 |
| 1 | Vente | 95000 |
| 1 | Vente | 100000 |
| 1 | Achat | 88500 |
| 1 | Achat | 90500 |
| 1 | Achat | 90500 |
| 2 | Achat | 0 |
+-------------------------+-------+--------+
10 rows in set (0.00 sec)
Result log :
C:\Users\QuentinB\Google Drive\Desktop\temp>node app.js
GI_ACHAT
begining carnet_achat.display | List.length : 0
GE_ACHAT
begining carnet_achat.display | List.length : 4
row 0 : 90500
row 1 : 90500
row 2 : 88500
row 3 : 0
It should be :
C:\Users\QuentinB\Google Drive\Desktop\temp>node app.js
GI_ACHAT
begining carnet_achat.display | List.length : 3
row 0 : 90500
row 1 : 90500
row 2 : 88500
GE_ACHAT
begining carnet_achat.display | List.length : 1
row 0 : 0
It seems that the result of the query done from the first object, GI, is received by the second object GE.
I tried to delay the creation of the second object with : setTimeout(function(){GE = new Zone(2, connectionB);},10); and it worked.
But I don't want to have to delay every creation, because I have 40 more objects to instanciate.
What can I do if I want to be sure the results of my queries are received by the right object?
Thanks for reading !
Since you're not declaring rCarnet_achat with the var keyword, you're implicitly declaring it as a global variable. So, each time you call rCarnet_achat.addElement(ordreToAdd);, you're actually adding elements to the same Carnet_achat instance. This could be fixed by adding var rCarnet_achat; to the top of the Zone function.
p.s. your code is riddled with other problems, e.g.
You should use node-mysql's query string escaping to avoid SQL injection attacks, e.g. aConnection.query("SELECT * FROM Ordre WHERE Entreprise_idEntreprise = ? AND Sens = 'Achat' ORDER BY Valeur DESC;", aIdZone, aCallback)
Using a setTimeout to wait for your SQL query to finish is wrong. Just wait for the callback.
Since you have "40 more objects to instanciate", you might consider writing a single query to fetch them all at once, e.g. select * from foo where id in (1,2,3);