cannot retain id of first table in left join - mysql

I am using sails waterline ORM and i have three tables in my model layer
1-s_class
attributes: {
c_title:{
type:'string',
required: true
},
sec:{
collection:'s_section',
via:"cls"
},
s_session:{
model:'s_session',
columnName:'session'
}
}
2-s_section
attributes: {
sec_title:{
type:'string'
},
sec_priority:{
type:'integer',
required: true
},
cls:{
collection:'s_class',
via:"sec"
}
}
3-s_form
attributes: {
studentName:{
type:'string'
},
s_class:{
columnName:'s_class',
model:'s_class'
},
s_section:{
columnName:'s_section',
model:'s_section'
}
}
i assigned both class and section to student which are saved in s_form table.when i write a query to get a student's record alongwith his class and section.something like this:
s_form.query("SELECT * FROM s_form LEFT OUTER JOIN s_class ON s_form.s_class=s_class.id LEFT OUTER JOIN s_section ON s_form.s_section=s_section.id",function(err,forms){
if(!err)
else{
res.json(forms);
}
});
it populates record of section and class but also affects auto increment primery key of s_form.actually this is because s_section and s_class also have default auto increment primery keys which after populating conflicts and in this case i got id of s_section.
i want to get id of s_form.is there any way to avoid this conflict and overriding of id without affecting default behavior of primery keys????
Note
s_form table contains custom columns means the columns mentioned above are static but it also contain columns which are created at runtime.that's why i can't use built in populate() query method nor i can specify column names like instead of select *.....

Based on your edited / updated post you I would query query to retrieve your column names prior to executing the query so that you can iterate over them and pass the table name as a prefix to each column name. This would allow you to avoid any conflicts.
You can use the following to get column names
SELECT *
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='yourdatabasename'
AND `TABLE_NAME`='yourtablename';
You can use this after your dynamic tables are created and save it in a variable so you don't have to keep doing it on every query.

Well, first you can have sails do this for you
s_form.find().populate('').populate('').exec(function(err,forms){/*....*/});
If you want to use query then you need to explicitly name your fields in order to avoid the conflict that will happen.
Instead of SELECT * FROM
You should specific each field so can rename the Id field to avoid these conflicts.
SELECT
s_class.c_title, s_class.id as classId,
s_section.sec_title,s_section.sec_priority,s_section.id as sectionId,
s_form.studentName,s_form.id as formId
FROM FROM s_form LEFT OUTER JOIN s_class ON s_form.s_class=s_class.id LEFT OUTER JOIN s_section ON s_form.s_section=s_section.id

Related

ADF dataflow and columns/rows in separate array in JSON

I have a bunch of json files which have an array with column names and a separate array for the rows.
I want a dynamic way of retrieving column names and merge them with the rows for each json file.
Been playing around with derived columns and column patterns, but struggling to get it working.
I want the column names from [data.column.shortText] and values for each corresponding [data.rows.value] according to the order.
Example format
{
"messages":{
},
"data":{
"columns":[
{
"columnName":"SelectionCriteria1",
"shortText":"Case no."
},
{
"columnName":"SelectionCriteria2",
"shortText":"Period for periodical values",
},
{
"columnName":"SelectionCriteria3",
"shortText":"Location"
},
{
"columnName":"SelectionCriteriaAggregate",
"shortText":"Value"
}
],
"rows":[
[
{
"value":"23523"
},
{
"value":12342349
},
{
"value":"234234",
"code":3342
},
{
"value":234234234
}
]
]
}
}
First, you need to fix your Json data, i can see you have an extra comma in columns second Json and in rows you have value as int and as string so when i tried to parse it in ADF i got an error.
i don't quite understand why you're trying to do merge by position because normally we get rows more than columns, and if you'll get 5 rows and 3 columns you will get an error.
Here is my approach to your problem:
the main idea is that i added index column to both arrays and joined the jsons by Inner Join.
created a Source Data (its 2 but you can make it one to simplify your data flow)
added Select activity to select relevant arrays from the data.
flattened the array(in order to add index column)
added index by using rank activity (please read more about rank and dense rank and what is the difference between the two)
added a Join activity , inner join by index column.
Select activity to remove index column from the result.
saved output to sink.
Json Data that i worked with:
Data Flow:
SelectRows Activity:
Flatten Activity:
Rank actitity:
Join activity:
please check these links:
https://learn.microsoft.com/en-us/azure/data-factory/data-flow-expressions-usage#mapAssociation
https://learn.microsoft.com/en-us/azure/data-factory/data-flow-map-functions

Using json_extract in sqlite to pull data from parent and child objects

I'm starting to explore the JSON1 library for sqlite and have been so far successful in the basic queries I've created. I'm now looking to create a more complicated query that pulls data from multiple levels.
Here's the example JSON object I'm starting with (and most of the data is very similar).
{
"height": 140.0,
"id": "cp",
"label": {
"bind": "cp_label"
},
"type": "color_picker",
"user_data": {
"my_property": 2
},
"uuid": "948cb959-74df-4af8-9e9c-c3cb53ac9915",
"value": {
"bind": "cp_color"
},
"width": 200.0
}
This json object is buried about seven levels deep in a json structure and I pulled it from the larger json construct using an sql statement like this:
SELECT value FROM forms, json_tree(forms.formJSON, '$.root')
WHERE type = 'object'
AND json_extract(value, '$.id') = #sControlID
// In this example, #sControlID is a variable that represents the `id` value we're looking for, which is 'cp'
But what I really need to pull from this object are the following:
the value from key type ("color_picker" in this example)
the values from keys bind ("cp_color" and "cp_label" in this example)
the keys value and label (which have values of {"bind":"<string>"} in this example)
For that last item, the key name (value and label in this case) can be any number of keywords, but no matter the keyword, the value will be an object of the form {"bind":"<some_string>"}. Also, there could be multiple keys that have a bind object associated with them, and I'd need to return all of them.
For the first two items, the keywords will always be type and bind.
With the json example above, I'd ideally like to retrieve two rows:
type key value
color_picker value cp_color
color_picker label cp_label
When I use json_extract methods, I end up retrieving the object {"bind":"cp_color"} from the json_tree table, but I also need to retrieve the data from the parent object. I feel like I need to do some kind of union, but my attempts have so far been unsuccessful. Any ideas here?
Note: if the {"bind":"<string>"} object doesn't exist as a child of the parent object, I don't want any rows returned.
Well, I was on the right track and eventually figured out it. I created a separate query for each of the items I was looking for, then INNER JOINed all the json_tree tables from each of the queries to have all the required fields available. Then I json_extracted the required data from each of the json fields I needed data from. In the end, it gave me exactly what I was looking for, though I'm sure it could be written more efficiently.
For anyone interested, this is what hte final query ended up looking like:
SELECT IFNULL(json_extract(parent.value, '$.type'), '_window_'), child.key, json_extract(child.value, '$.bind') FROM (SELECT json_tree.* FROM nui_forms, json_tree(nui_forms.formJSON, '$') WHERE type = 'object' AND json_extract(nui_forms.formJSON, '$.id') = #sWindowID) parent INNER JOIN (SELECT json_tree.* FROM nui_forms, json_tree(nui_forms.formJSON, '$') WHERE type = 'object' AND json_extract(value, '$.bind') != 'NULL' AND json_extract(nui_forms.formJSON, '$.id') = #sWindowID) child ON child.parent = parent.id;
If you have any tips on reducing its complexity, feel free to comment!

mysql query works in phpmyadmin but not in node.js

I have a query like this...
SELECT *
FROM `000027`,`000028`
WHERE `000027`.id=(SELECT max(`000027`.id) FROM `000027`)
AND `000028`.id=(SELECT max(`000028`.id) FROM `000028`)
which returns something like this in phpmyadmin...
id time value id time value
However, in react.js it is only returning one of these like this...
id time value
2 questions, Why is it doing this? and, how can I get it to return both instead of one?
my node.js code...
const sqlSelect = "SELECT * FROM `000027`,`000028` WHERE `000027`.id=(SELECT max(`000027`.id) FROM `000027`) AND `000028`.id=(SELECT max(`000028`.id) FROM `000028`)"
dbPlant.query(sqlSelect, (err, result) => {
console.log(result)
res.send(result)
res.end()
})
and it sends this back with only one rowdatapacket when it should be two, or two of each of those values...
[
RowDataPacket {
id: 652,
time: 2021-01-24T17:28:01.000Z,
value: '262'
}
]
Your two tables have some column names in common. This is okay to have repeated column names in a result set in the mysql client, but some programming interfaces map a rows of a result set into a hash array, where the column names are the keys. So if you have duplicate column names, one naturally overwrites the other.
The remedy is to define column aliases for one or the other of each duplicate, so they are mapped into distinct keys in the result set.
You must do this one column at a time. Sorry, you can't use SELECT * anymore (you shouldn't use SELECT * anyway). There is no "automatic alias all columns" option.
SELECT
`000027`.id AS id27,
`000027`.time AS time27,
`000027`.value AS value27,
`000028`.id AS id28,
`000028`.time AS time28,
`000028`.value AS value28
FROM `000027`,`000028`
WHERE `000027`.id=(SELECT max(`000027`.id) FROM `000027`)
AND `000028`.id=(SELECT max(`000028`.id) FROM `000028`)

Importing CSV While Creating Relationship In Neo4j

I am trying to create a relationship between two different graphs, using information in a CSV file. I built the query the way I did because the size of each graph, one being 500k+ and the other 1.5m+.
This is the query I have:
LOAD CSV WITH HEADERS FROM "file:///customers_table.csv" AS row WITH row
MATCH (m:Main) WITH m
MATCH (c:Customers) USING INDEX c:Customers(customer)
WHERE m.ASIN = row.asin AND c.customer = row.customer
CREATE (c)-[:RATED]->(m)
This is the error I receive:
Variable `row` not defined (line 4, column 16 (offset: 164))
"WHERE m.ASIN = row.asin AND c.customer = row.customer"
^
An example of the Main table is:
{
"ASIN": "0827229534",
"totalreviews": "2",
"categories": "2",
"title": "Patterns of Preaching: A Sermon Sampler",
"avgrating": "5",
"group": "Book"
}
And an example of a customer is:
{
"customer": "A2FMUVHRO76A32"
}
And inside the customers table csv, I have:
Customer, ASIN, rating
A2FMUVHRO76A32, 0827229534, 5
I can't seem to figure out why it's throwing back that error.
The first WITH clause in your query (WITH row) is unnecessary, but you have to add the variable to the WITH clause. So this version compiles.
LOAD CSV WITH HEADERS FROM "file:///customers_table.csv" AS row
MATCH (m:Main)
WITH m, row
MATCH (c:Customers) USING INDEX c:Customers(customer)
WHERE m.ASIN = row.asin AND c.customer = row.customer
CREATE (c)-[:RATED]->(m)
The reason for this is, that, in essence, WITH chains two query parts together, while limiting the scope to its variables (and in some cases, also performing calculations, aggregations, etc.).
Having said that, you do not even need the second WITH clause, you can just omit it and even merge the two MATCH clauses to a single one:
LOAD CSV WITH HEADERS FROM "file:///customers_table.csv" AS row
MATCH (m:Main), (c:Customers) USING INDEX c:Customers(customer)
WHERE m.ASIN = row.asin AND c.customer = row.customer
CREATE (c)-[:RATED]->(m)

DBIx::Class Temporary column

I am using DBIx::Class and I have a query like this:
$groups = $c->model('DB::Project')->search(
{ "sessions.user_id"=>$c->user->id,done_yn=>'y' },
{
select => ["name", "id",\'SUM(UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(start_time)) as total_time'], #\''
join => 'sessions',
}
);
I'd like to be able to get the value of SUM(UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(start_time)), but because this is not a real column in the table, referencing total_time for a DBIx::Class::Row object doesn't seem to work. Does anyone know how I can get these temporary columns? Thanks!
The select docs describe perfectly how to achieve what you're trying to accomplish.
It's also recommended to avoid literal SQL when possible, you can use { sum => \'UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(start_time)' } instead.
The 'as' in the literal SQL isn't required to give the column a name, you have to use either the as search attribute or better the columns shortcut instead of select+as.