I'm trying tu use the AlaSQL Array agregator inside an array, it appears to be not supported :(
Trying to acomplish this output (or like this):
[
{
"keyword":"project 1",
"projects": [
{
"year":2014,
"description":"this is a project description",
"budget": 5600,
"status": "closed",
"metadata": [
{
"key":"provider",
"value":"just me"
},
{
"key":"client",
"value":"someone"
},
{
"key":"any thing",
"value":"any data..."
}
]
}
]
}
]
My Database Structure
people e
| name | type |
|-----------|---------|
| name | varchar |
| lastname | varchar |
| person_id | varchar |
| cel | int |
projects p
| name | type |
|-------------|---------|
| keyword | varchar |
| year | int |
| description | text |
| budget | int |
PeopleProjects x
| name | type |
|-------------|---------|
| e_person_id | varchar |
| p_keyword | varchar |
| p_year | int |
| status | varchar |
metadata m
| name | type |
|-------------|---------|
| e_person_id | varchar |
| p_keyword | varchar |
| p_year | int |
| key | varchar |
| value | varchar |
My query
alasql("SELECT p.keyword, \
ARRAY({year:p.year, description:p.description, budget:p.budget, status:x.status, \
ARRAY({key:m.key, value:m.value}) as metadata \
}) AS projects \
FROM projects p, PeopleProjects x, metadata m \
WHERE \
p.keyword = x.p_keyword AND x.p_keyword = m.p_keyword AND \
p.year = x.p_year AND x.p_year = m.p_year \
x.e_person_id = x.e_person_id AND AND x.e_person_id = 2 \
GROUP BY p.keyword");
At the moment, I divided the query in two and then combine the data to produce the hole thing.
Any ideas?
I managed to get the output I want by fetching two times:
First, projects:
var projects = alasql("SELECT p.keyword, ARRAY({status:x.status, year:p.year, description:p.description, budget:p.budget }) AS years \
FROM PeopleProjects x, projects p \
WHERE x.p_keyword = p.keyword AND x.p_year = p.year AND x.e_person_id = "+person_id+" \
GROUP BY p.keyword");
Second, metadata:
var mdata = alasql("SELECT m.e_person_id, m.p_keyword, m.p_year, ARRAY({key:m.key,value:m.value}) as [metadata] \
FROM metadata m, PeopleProjects x \
WHERE x.e_person_id = m.e_person_id AND x.p_keyword = m.p_keyword AND x.p_year = m.p_year AND x.e_person_id = "+person_id+" \
GROUP BY m.e_person_id, m.p_keyword, m.p_year");
Then, loop over projects, searching and storing the metadata:
for(i=0;i<projects.length;i++){
for(j=0;j<projects[i].years.length;j++){
current = projects[i].keyword;
current_year = projects[i].years[0].year;
search = alasql("SEARCH / * WHERE(year="+current_year+" AND keyword='"+current+"') FROM ?",[mdata]);
projects[i].years[j]["metadata"] = search[0].metadata;
}
}
Now projects has all the data.
Any suggestion will be welcome.
Related
I have 2 tables and using the hasOne to join them.
Table A
| name | value | time |
| ---- | ----- | --------- |
| John | 1 | 2022-01-02|
| John | 2 | 2022-03-04|
User.hasOne(
A,
{
sourceKey: 'name',
foreignKey: 'name',
as: 'name',
scope: {
default: where(col('User.name'), '=', col('data.name')),
},
},
);
Now, is it possible to add an order by time in there? So I always get the latest record?
I have two tables, metadata and view_events. Both metadata and view_events have config_id and config_type columns. I'm trying to select all view_events for a given user email, distinct by config_id and config_type, ordered by timestamp, desc, and limited to the 10 most recent. The following knex.js code isn't working but hopefully expresses what I'm trying to achieve:
return dbClient<AuthenticatedUserIndexRow>(METADATA_TABLE_NAME)
.select([
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.CONFIG_ID}`,
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.CONFIG_TYPE}`,
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.DESCRIPTION}`,
`${VIEW_EVENTS_TABLE_NAME}.${VIEW_EVENTS_COLUMNS.TIMESTAMP}`,
])
.innerJoin<AuthenticatedUserIndexRow>(VIEW_EVENTS_TABLE_NAME, function innerJoinOnViewEvents() {
this.on(
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.STORAGE_ID}`,
'=',
`${VIEW_EVENTS_TABLE_NAME}.${VIEW_EVENTS_COLUMNS.CONFIG_STORAGE_ID}`,
)
.andOn(
`${VIEW_EVENTS_TABLE_NAME}.${VIEW_EVENTS_COLUMNS.USER_EMAIL}`,
'=',
rawSql('?', [authUserEmail]),
)
.andOn(`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.DELETED}`, '=', rawSql('?', [false]));
})
.distinct([
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.CONFIG_TYPE}`,
`${METADATA_TABLE_NAME}.${METADATA_COLUMNS.CONFIG_ID}`,
])
.limit(EVENT_LIMIT)
.orderBy(VIEW_EVENTS_COLUMNS.TIMESTAMP, 'desc');
For example, given the following tables:
view_events
+-------------+-----------+--------------------------+----------------------+
| config_type | config_id | timestamp | email |
+-------------+-----------+--------------------------+----------------------+
| a | foo | 2020-01-23T03:08:14.618Z | john.smith#gmail.com |
| a | foo | 2020-01-23T03:08:14.500Z | jane.doe#gmail.com |
| a | foo | 2020-01-23T03:08:13.618Z | john.smith#gmail.com |
| a | bar | 2020-01-23T03:08:12.618Z | john.smith#gmail.com |
| a | foo | 2020-01-23T03:08:11.618Z | john.smith#gmail.com |
| b | foo | 2020-01-23T03:08:10.618Z | john.smith#gmail.com |
| a | baz | 2020-01-23T03:08:09.618Z | john.smith#gmail.com |
| a | foo | 2020-01-23T03:08:08.618Z | john.smith#gmail.com |
+-------------+-----------+--------------------------+----------------------+
metadata
+-------------+-----------+---------------------------+
| config_type | config_id | description |
+-------------+-----------+---------------------------+
| a | foo | Type a config with id foo |
| a | bar | Type a config with id bar |
| b | foo | Type b config with id foo |
| a | baz | Type a config with id baz |
+-------------+-----------+---------------------------+
I am trying to obtain the following output (given an authUserEmail of john.smith#gmail.com):
+-------------+-----------+---------------------------+
| config_type | config_id | description |
+-------------+-----------+---------------------------+
| a | foo | Type a config with id foo |
| a | bar | Type a config with id foo |
| b | foo | Type b config with id foo |
| a | baz | Type a config with id baz |
+-------------+-----------+---------------------------+
I'm not a SQL expert, but am generally aware that the use of SELECT and DISTINCT together here doesn't work. What's the correct approach?
Does the following roughly work for you? I did using with as so we could grab the 10 most recent configs (max(timestamp)..group by config) and then remove the timestamp column in the final projection. Note the final records may not appear in exact timestamp order as you did not want timestamp in your final output, but they will be the 10 most recent. I haven't added the DELETED column but imagine you will re-add that based on the code in your question.
knex.with('ordered_items', (qb) =>
qb.table('metadata')
.innerJoin('view_events', function() {
this.on('metadata.config_id', '=', 'view_events.config_id')
.andOn('metadata.config_type', '=', 'view_events.config_type')
})
.where({'view_events.email': 'john.smith#gmail.com'})
.select(['metadata.config_type', 'metadata.config_id',
'metadata.description'])
.max('view_events.timestamp', {as: 'max_ts'})
.groupBy(['metadata.config_id', 'metadata.config_type', 'metadata.description'])
.orderBy('max_ts', 'desc')
.limit(10))
.table('ordered_items')
.select(['config_type', 'config_id', 'description'])
My input and output:
sqlite> select * from metadata;
a|foo|Type a config with id foo
a|bar|Type a config with id bar
b|foo|Type b config with id foo
a|baz|Type a config with id baz
sqlite> select * from view_events;
a|foo|2020-01-23T03:08:14.618Z|john.smith#gmail.com
a|foo|2020-01-23T03:08:14.500Z|jane.doe#gmail.com
a|foo|2020-01-23T03:08:13.618Z|john.smith#gmail.com
a|bar|2020-01-23T03:08:12.618Z|john.smith#gmail.com
a|foo|2020-01-23T03:08:11.618Z|john.smith#gmail.com
b|foo|2020-01-23T03:08:10.618Z|john.smith#gmail.com
a|baz|2020-01-23T03:08:09.618Z|john.smith#gmail.com
a|foo|2020-01-23T03:08:08.618Z|john.smith#gmail.com
[ { config_type: 'a',
config_id: 'foo',
description: 'Type a config with id foo' },
{ config_type: 'a',
config_id: 'bar',
description: 'Type a config with id bar' },
{ config_type: 'b',
config_id: 'foo',
description: 'Type b config with id foo' },
{ config_type: 'a',
config_id: 'baz',
description: 'Type a config with id baz' } ]
I have 3 Mysql tables, a vendor table with a list of vendors, a categories table with a list of categories that these vendors have in there stores, the categories table is linked to to the vendors table with a secondary key(vendor_id), i also have a product table that has all the products in these categories and it is linked to the category table using a foreign key (category_id). How do i write a NodeJs/ express route that returns a json object that looks like this,
{
"id": 1,
"vendor": "Food place",
"category": "Chicken"[
{
"id": "1,
"name": "Fried chicken",
"price": "100"
},
{
"id": "2,
"name": "Soup Chicken",
"price": "150"
}
}
So the json object returns a vendor all the categories they have in there store, and inside the categories all the products that be long to these categories
The tables look similar to this
Vendor table:
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | | NULL | |
| category | varchar(255) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
Category table:
+-----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| vendor_id | int(11) | NO | MUL | NULL | |
+-----------+-------------+------+-----+---------+----------------+
Product table:
+-----------------+---------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| price | decimal(10,0) | NO | | NULL | |
| name | varchar(255) | YES | | NULL | |
| category_id | int(11) | YES | MUL | NULL | |
+-----------------+---------------+------+-----+---------+----------------+
Route
export const route = (router: any) => {
return router.get('/your_route_here', (req: any, res: any) => {
// do your logic here
});
}
export default route;
I need make a group with result of 2 columns and separate by lines from name and columns from size.
Example: Table Base
Name | Size | Item
Frankincense | 5ml | 1562
Frankincense | 10ml | 1563
Frankincense | 15ml | 1564
Geranium | 5ml | 1565
Geranium | 10ml | 1566
Geranium | 15ml | 1567
Ginger | 5ml | 1568
Ginger | 10ml | 1569
Ginger | 15ml | 1570
Grapefruit | 5ml | 1571
Grapefruit | 10ml | 1572
Grapefruit | 15ml | 1573
Lavender | 5ml | 1574
Lavender | 10ml | 1575
Lavender | 15ml | 1576
Example: Table Result
Name/Size | 5ml | 10ml | 15ml
Frankincense | 1562 | 1563 | 1564
Geranium | 1565 | 1566 | 1567
Ginger | 1568 | 1569 | 1570
Grapefruit | 1571 | 1572 | 1573
Lavender | 1574 | 1575 | 1576
I found something, but don't have the result yet. I need group the column size and made sure the result is correct.
data = [['Frankincense','5ml','1562'],
['Frankincense','10ml','1563'],
['Frankincense','15ml','1564'],
['Geranium','5ml','1565'],
['Geranium','10ml','1566'],
['Geranium','15ml','1567'],
['Ginger','5ml','1568'],
['Ginger','10ml','1569'],
['Ginger','15ml','1570'],
['Grapefruit','5ml','1571'],
['Grapefruit','10ml','1572'],
['Grapefruit','15ml','1573'],
['Lavender','5ml','1574'],
['Lavender','10ml','1575'],
['Lavender','15ml','1576']]
data.sort()
var title = data.reduce(function(result, value) {
if ( result.indexOf(value[1]) === -1 ) {
result.push(value[1]);
}
return result;
}, []).map(function(group) {
return group
});
var result = data.reduce(function(result, value) {
if ( result.indexOf(value[0]) === -1 ) {
result.push(value[0]);
}
return result;
}, []).map(function(group) {
return [group,...data.filter(function(_el) {
return _el[0] === group;
}).map(function(_el) { return _el[2]; })]
});
title.unshift('Name/Size')
result.unshift(title)
result.forEach(item => console.log(item.join('\t| ')))
I know there are similar questions but they haven't help me.
I've got an error when trying to use .find() method on model: product2
(.query() method is working )
I was trying to find out how to get more verbose output from database, but with failure.
{
"error": "E_UNKNOWN",
"status": 500,
"summary": "Encountered an unexpected error",
"raw": {
"code": "ER_BAD_FIELD_ERROR",
"errno": 1054,
"sqlState": "42S22",
"index": 0
}
}%
my model "Product2.js"
module.exports = {
connection:'someMysqlServer',
migration:'safe',
tableName:'NUTR_DATA',
attributes:{
id:{
columnName:'Nutr_No',
primaryKey:true,
type:'string'
}
}
};
routes.js
module.exports.routes{
'GET /select':'Product2Controller.select'
};
Product2Controller.js
module.exports = {
select:function(req,res){
Product2.find({limit:10}).exec(function(err, results) {
if (err){res.serverError(err)}
else{res.json(results)};
});
}
};
database schema
+---------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| NDB_No | varchar(5) | NO | PRI | NULL | |
| Nutr_No | varchar(3) | NO | PRI | NULL | |
| Nutr_Val | decimal(13,3) | NO | | NULL | |
| Num_Data_Ptr | decimal(10,0) | NO | | NULL | |
| Std_Error | decimal(11,3) | YES | | NULL | |
| Src_Cd | varchar(2) | NO | | NULL | |
| Deriv_cd | varchar(4) | YES | | NULL | |
| Ref_NDB_No | varchar(5) | YES | | NULL | |
| Add_Nutr_Mark | varchar(1) | YES | | NULL | |
| Num_Studies | int(11) | YES | | NULL | |
| Min | decimal(13,3) | YES | | NULL | |
| Max | decimal(13,3) | YES | | NULL | |
| DF | int(11) | YES | | NULL | |
| Low_EB | decimal(13,3) | YES | | NULL | |
| Up_EB | decimal(13,3) | YES | | NULL | |
| Stat_cmd | varchar(10) | YES | | NULL | |
| AddMod_Date | varchar(10) | YES | | NULL | |
| CC | varchar(1) | YES | | NULL | |
+---------------+---------------+------+-----+---------+-------+
Any ideas as to what is going wrong?
Thank you for your responses. The problem was not setted
autoCreatedAt: false,
autoUpdatedAt: false
i hadn't see that my ide actually give me more verbose output then curl. Maybe it would be better if errors would be placed under calming picture of boat and info about lifted server :P
The likely problem is that you're defining your own primary key field, but Waterline is still atuomatically adding its own id field. You can turn off this behavior by adding autoPK: false to your model configuration. Docs for autoPK are here.