Manipulating Javascript Object Format - javascript

I am trying to receive all of the players under a certain team along with the team's id.
Here is my query:
SELECT player.team_id, team.name, player.first_name, player.last_name FROM player, team WHERE player.team_id = team.id AND player.league = "League 1";
I am taking the result (stored in teams) and sending it to my client by doing this:
res.send({
success: true,
teams: teams
});
Here is what it returns when I reach its endpoint:
I want to reformat this date to where I get one field for each unique team. It should have a players field (array) inside so I can access the names of each player part of the team. Does anyone know how I can manipulate this data to that format?
So for example, for this data set, inside the teams object, there would only be one field named "Warriors" with a players array that has all of those people's name inside of it.
I tried following the answer, but now it's just returning it as a string, not an actual object.

You can use aggrgation and json functions:
select
t.team_id,
t.name,
json_array_agg(
json_object('first_name', p.first_name, 'last_name', p.last_name)
) as players
from teams t
inner join players p on p.team_id = t.team_id
group by t.team_id, t.name
The third column in the resultset is a json array that contains json objects that represent the players, with keys first_name and last_name.
You can also aggregate the whole resulset as a json array, with another level of aggreation:
select json_array_agg(
json_object('team_id', team_id, 'name', name, 'players', players)
) res
from (
select
t.team_id,
t.name,
json_array_agg(
json_object('first_name', p.first_name, 'last_name', p.last_name)
) as players
from teams t
inner join players p on p.team_id = t.team_id
group by t.team_id, t.name
) t
Edit: json_array_agg() is available starting version 10.5.0 only. In earlier versions, an alternative is string concatenation:
select
t.team_id,
t.name,
concat(
'[',
group_concat(json_object('first_name', p.first_name, 'last_name', p.last_name)),
']'
) as players
from teams t
inner join players p on p.team_id = t.team_id
group by t.team_id, t.name

Related

Find the sum of a Column with group by and Joins in one Query using Sequelize ORM

Hi Hope you all are doing well I am using Sequelize ORM in node js I have to sum the final price of orders of one day and display the data so i want to find the some of final prices group by "createdAt" field but not able to use group by "createdAt" as i have made joins with other tables in the same query
Order.findAll(
{
logging:console.log,
subQuery:false,
include:[
{
model: fulfillments,
required:true,
attributes:['fulfillment_status_id' , 'order_id'],
include:{
model:fulfillmentStatus,
where:{
delivery_status_name:fulfillmentStatusEnum.completed
}
}
}
],
attributes:['final_price', 'createdAt'],
}
)
the results i got from the above query was
SELECT "Order"."id", "Order"."final_price", "Order"."createdAt", "fulfillments"."id" AS "fulfillments.id", "fulfillments"."fulfillment_status_id" AS "fulfillments.fulfillment_status_id", "fulfillments"."order_id" AS "fulfillments.order_id", "fulfillments->fulfillmentStatus"."id" AS "fulfillments.fulfillmentStatus.id", "fulfillments->fulfillmentStatus"."delivery_status_name" AS "fulfillments.fulfillmentStatus.delivery_status_name", "fulfillments->fulfillmentStatus"."createdAt" AS "fulfillments.fulfillmentStatus.createdAt", "fulfillments->fulfillmentStatus"."updatedAt" AS "fulfillments.fulfillmentStatus.updatedAt" FROM "Orders" AS "Order" INNER JOIN "fulfillments" AS "fulfillments" ON "Order"."id" = "fulfillments"."order_id" INNER JOIN "fulfillmentStatuses" AS "fulfillments->fulfillmentStatus" ON "fulfillments"."fulfillment_status_id" = "fulfillments->fulfillmentStatus"."id" AND "fulfillments->fulfillmentStatus"."delivery_status_name" = 'completed';
but i want to acive the query mentioned blow:
select sum(final_price) , "Orders"."createdAt" from "Orders" INNER JOIN fulfillments on fulfillments.order_id = "Orders".id INNER JOIN "fulfillmentStatuses" on fulfillments.fulfillment_status_id = "fulfillmentStatuses"."id" where "fulfillmentStatuses".delivery_status_name = 'completed' GROUP BY "Orders"."createdAt"
can any one help?

How to query table results with m,n-relationships to a different table with (unnecessarily) LEFT JOINs?

Please advise on a better formulation of the question.
Basis
I have SQL tables R=recipes, I=ingredients. (minimum example):
R (id)
RI (id, r_id, i_id)
I (id, description)
where RI is intermediate table connecting R and I (otherwise in m,n-relationship).
You may skip this
In HTML I have an input for filtering recipes by ingredients. Input is sent to PHP with JavaScript's Fetch API (body: JSON.stringify({ input: filter.value.trim() })).
In PHP I clean it up and explode it into array of words so %&/(Oh/$#/?Danny;:ยค boy! gets converted to ['Oh', 'Danny', 'boy']
$filterParams = preg_replace('/[_\W]/', ' ', $data['input']);
$filterParams = preg_replace('/\s\s+/', ' ', $filterParams);
$filterParams = trim($filterParams);
$filterParams = explode(' ', $filterParams);
What I want
I need an SQL query for all recipe IDs that require all of the ingredients from the input. Consider these two recipes:
ID RECIPE INGREDIENTS
1 pancake egg, flour, milk
2 egg egg
Filtering for "eg, ilk" should only return 1 but not 2.
What I have #1
This gives me all recipes that require any of the ingredients, therefore it returns 1 and 2.
$recipeFilters = array_map(function ($param) {
return "ri.description LIKE '%{$param}%'";
}, $filterParams);
$recipeFilter = implode(' OR ', $recipeFilters);
$selRecipes = <<<SQL
SELECT DISTINCT rr.id
FROM
recipe_ingredient ri LEFT JOIN
recipe_intermediate_ingredient_recipe riir ON riir.ingredient_id = ri.id LEFT JOIN
recipe_recipe rr ON rr.id = riir.recipe_id
WHERE
{$recipeFilter} AND
rr.id IS NOT NULL
SQL;
$recipes = data_select($selRecipes); // Custom function that prepares statement, binds data (not in this case), and eventually after all error checking returns $statement->get_result()->fetch_all(MYSQLI_ASSOC)
$ids = [];
foreach ($recipes as $recipe)
$ids[] = "{$recipe['id']}";
What I have #2
Replacing OR with AND in the fifth line returns neither 1 nor 2, because no ingredient has both eggs and milk (ie. eg, ilk) in it's name.
...
$recipeFilter = implode(' AND ', $recipeFilters);
...
Suboptimal solution
I know I can simply query for each ingredient separately and then with some simple array manipulations get what I desire.
Is it possible to do it in just one query, and how?
You could use a query with grouping in combination with HAVING COUNT() to get the desired result.
recipe
id
name
1
pancakes
2
eggs
ingredient
id
name
1
eggs
2
flour
3
milk
recipe_ingredient
rid
iid
1
1
1
2
1
3
2
1
Consider this query:
SELECT r.id, r.name FROM recipe r
JOIN recipe_ingredient ri ON r.id = ri.rid
JOIN ingredient i ON i.id = ri.iid
WHERE i.name LIKE '%ilk%' OR i.name LIKE '%eg%'
GROUP BY r.id
HAVING COUNT(i.name) = 2;
This query selects the recipes, joins the ingredients, and groups by recipe ID, using HAVING COUNT(i.name) to count the ingredients matching the OR filters, which gives you:
id
name
1
pancakes

Parse.com match all pointers on array in given relation column

I have Conversation classes with a members relation attribute pointing to User class.
This members attribute consists of people belong to a particular conversation.
Now I want to query if given array of pointers User is part of particular conversation given that all elements must match.
I tried to use containsAll("members", users) but instead got undefined.
containedIn() worked but it returned all matching conversation that has at least one matching User in array.
equalTo("members", users) was not working as well and note that the users variable is array of pointers and not just array of strings objectId, but I also tried that one but got me nowhere.
Here's what I tried:
* Created AND queries where userRelationQuery.equalTo('member', ParseUser1) up to N number of users and still didn't work
Here's my solution but feel free to correct this for improvement
const members = getMembers();
let query = new Parse.Query("Conversation").equalTo(
"members",
members[0]
);
for (let i = 0; i < members.length; i++) {
query = new Parse.Query("Conversation")
.matchesKeyInQuery("objectId", "objectId", query)
.equalTo(
"members",
members[i]
);
}
const chat = await query.includeAll().first();
This should work for you
var conversationClass = Parse.Object.extend('Conversation');
var conversationQuery = new Parse.Query(conversationClass);
return conversationQuery.first()
.then(queryResult => {
var userRelationQuery = queryResult.relation('members').query(); //You can get all users releated to this conversation
//userRelationQuery.equalTo('username', 'Blank0330') // Or you can add more conditions
return userRelationQuery.find()
.then(users => {
return users; //This is your releated users
});
});
For more information about Parse-JS-SDK Relation

JS and ExpressionEngine - Remove KV pairs by duplicate values only?

We're building a site with ExpressionEngine. We are running a SQL query to gather up all member IDs for a specific member group. After that, we are using EE tags to get data from a custom member field for each member ID.
The ID and field data need to stay paired, as we will be populating a drop-down so that the ID is the value and the field data is the text, so we are currently putting them into a JS array as key/value pairs. The call is as follows:
var array= [
{exp:query sql="SELECT * FROM exp_members WHERE group_id = 5"}
{exp:member:custom_profile_data
member_id="{member_id}"}
{if company != ''}
{{member_id}:"{company}"},
{/if}
{/exp:member:custom_profile_data}
{/exp:query}
};
This gives us the output:
var array = [
{1:"name01"},
{2:"name02"},
{3:"name01"},
{4:"name03"}
];
Now, our problem. We need to remove objects based on duplicate field data (values) only, so the above array would look like this:
var array = [
{1:"name01"},
{2:"name02"},
{4:"name03"}
];
None of these IDs (keys) will ever be the same, but the field data (values) can be. So we want to keep the first KV pair that comes through with a unique value, but remove any subsequent dupes of that value - despite the fact that they will not be true "duplicate values" due to a different ID (key).
Keeping in mind that the KV pairs are all dynamic, is there any possible way to do this via JS so we can create a new array for the cleaned data to pass to the drop-down?
You could handle the duplications by modifying your MySQL query. (In my example, my custom field ID was 1.)
var myArray = [];
{exp:query sql="SELECT MIN(m.member_id) AS co_member_id, d.m_field_id_1 AS company FROM exp_members m INNER JOIN exp_member_data d ON m.member_id = d.member_id WHERE d.m_field_id_1 != '' AND m.group_id > 0 GROUP BY d.m_field_id_1;"}
myArray.push({{co_member_id}: "{company}"});
{/exp:query}
This query would use the first (in the ordinal sense) member_id found; you could also change the MIN to MAX and get the last.
This will give you a clean output in your source, without the need for any additional JS processing. I'd also recommend changing the names of the variables you're outputting as to not conflict in EE's parsing.
I would do it like...
function removeDups(arry){
var tmp = {}, retainIdx=[], newArry=[];
arry.forEach(function(obj, idx){
var val = obj[Object.keys(obj)[0]];
if(val && !tmp[val]){
retainIdx.push(idx);
tmp[val] = true;
}
});
retainIdx.forEach(function(i){
newArry.push(arry[i]);
});
return newArry;
};

Create SQL sentece according to users input MySQL

what I want to do is this:
First have a form that has 5 input for example:
Name:
Career:
Experience:
City:
Speciality:
what I need to do is create a sql sentence according to the fields that are filled. If only 2 field were filled create a sql with only those fields. I don't have any idea how to do this besides creating a sql sentence for every possibility which turns out to be a pretty extensive work. i read that i could use store procedures, but again I don't know how I would do it. please help me!
well sorry if i didn't elaborate the question.
here is the deal i have diferent tables in mysql database
person
person_id
name
last_name
person_courses
person_id
course
person_carrer
person_id
carrer
person_experience
person_id
position
experience_description
experience_from_date
experience_to_date
all this tables are related to person by foreign_key (person_id)
then i have a page where user have 6 diferent inputs:
name:
last_name:
courses:
experience:(this fields search position and experience_description from table person_experience)
antiquity:(must obtain a sumatory of all person_experience)
the user must obtain results according to the fields he filled.
what i tried to do is create a complex SQL sentence using "%%" like this
select a.person_id, b.name, c.last_name, d.courses, f.experience, g.antiquity
from person a,
(
'SQL SENTENCE' WHERE NAME LIKE "%%"
) b,
(
'SQL SENTENCE' WHERE LAST_NAME LIKE "%%"
) c,
(
'SQL SENTENCE' WHERE COURSE LIKE "%%" GROUP BY PERSON_ID
) d,
(
'SQL SENTENCE' WHERE POSITION LIKE "%%" OR EXPERIENCE_DESCRIPTION LIKE "%%"
GROUP BY PERSON_ID
) f,
(
'SQL SENTECE'
WHERE 'SUMATORY OF ALL PERSON EXPERIENCE, (TO_DATE - FROM_DATE)/365 '>=0 (THIS ZERO WOULD CHANGE IF USER FILLS INPUT ANTIQUITY)
GROUP BY PERSON_ID
) g
WHERE a.person_id = b.person_id and c.person_id = b.person_id and d.person_id = c.person_id and f.person_id = d.person_id and g.person_id = f.person_id
and if the user fills any field i just put the value between '%value%' so this way i get the result, and i get results with this sql sentence but the problem is that if a person doesn't have a experience or carrer it is not shown in the result, so i need someway, as i said in the firstplace, just search in the database according to the users filled inputs.
for example in if the user fills:
carrer, experience: search all person with that carrer and that experience.
name: search all person even if they dont have carrer or course or experience with that name
PS: trying to create an sql sentece for every posibility would result in 64 sql senteces and i am not thinking about doing it!
THANK FOR ALL THE HELP IN ADVANCE
Here is something that may help:
$sql = array(); // initialize empty array for data
foreach(array("name", "career", "experience", "city", "speciality") as $key) { // iterate all the form controls
if(!empty($value = trim($_POST[$key]))) {
// the form input is filled, so we add it to data array (with proper escaping)
$sql["`".$key."`"] = "'".mysqli_real_escape_string($value)."'";
}
}
if(count($sql)) { // only if user had provided some data
// generate the final SQL statement
$sql = "INSERT INTO `table` ("
.implode(", ", array_keys($sql)).") VALUES (" // for example (`name`, `career`)
.implode(", ", array_values($sql)) . ")"; // for example ('Foo', 'Bar')
} else {
// no informations provided
}

Categories

Resources