I have really surprised about laravel relationship becasue it gives result without duplicate entries while if compare to left join.
for example recently i tried self join has many to same table
public function parentMenu(){
return $this->hasMany(Page::class,'parent_page_id','id');
}
and it return following result
Array
(
[0] => Array
(
[id] => 1
[page_name] => Branch Details
[page_url] => #
[parent_page_id] => 0
[page_type] => 1
[created_at] => 2018-06-23 23:45:34
[updated_at] => 2018-06-23 23:45:34
[deleted_at] =>
[slug] => branch_detail
[parent_menu] => Array
(
[0] => Array
(
[id] => 2
[page_name] => Add Branch Detail
[page_url] => add-branch
[parent_page_id] => 1
[page_type] => 1
[created_at] => 2018-06-23 23:45:54
[updated_at] => 2018-06-23 23:45:54
[deleted_at] =>
[slug] => add_branch_detail
)
[1] => Array
(
[id] => 11
[page_name] => View Branch Detail
[page_url] => list-branch
[parent_page_id] => 1
[page_type] => 1
[created_at] => 2018-06-23 23:46:08
[updated_at] => 2018-06-23 23:46:08
[deleted_at] =>
[slug] =>
)
)
)
also i have tried to figure out the query
Array
(
[0] => Array
(
[query] => select * from `pages` where `pages`.`deleted_at` is null
[bindings] => Array
(
)
[time] => 0.82
)
[1] => Array
(
[query] => select * from `pages` where `pages`.`parent_page_id` in (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) and `pages`.`deleted_at` is null
[bindings] => Array
(
[0] => 1
[1] => 2
[2] => 4
[3] => 5
[4] => 7
[5] => 8
[6] => 9
[7] => 10
[8] => 11
[9] => 12
)
[time] => 0.86
)
)
Now my question is suppose if i try to get same result what will be the mysql query .Since i want to know how internally relation query works ? will it do forloop internally or else in query itself it will produce result .
Also will it execute separate query in loop to retrieve child menu list ?
Laravel's active record implementation doesn't use joins for its relationships (well is does for some of them but that's for relationships like belongsToMany where it needs to use a pivot/intermediate table).
What will actually happen is Eloquent will get the related keys from the table and perform another query to get the required relationship e.g.
Post has many Comment and there are 3 posts in the db with ids 1, 2 and 3.
Post::with('comments')->get();
Will result in:
Query 1
SELECT * from `posts`
Query 2
SELECT * FROM `comments` WHERE `comment`.`post_id` in ('1', '2', '3')
It will hen go through the results from the 2nd query and match them to the models loaded from the first.
If you want to see what queries are being run from your Laravel app then I would suggest installing either:
Laravel Debugbar
Clockwork
Amongst other things, either of these tools will show you the queries that are being run.
Related
As mentioned above, I am trying to assign an alias to all columns of a table at once as there is an obvious problem in PDO if a column name is used in more than one table.
If I'm trying this SQL statement:
SELECT t12.*,t1.*,t2.* FROM `tableone2tabletwo` t12
LEFT JOIN tableone t1 ON t12.idone=t1.id
LEFT JOIN tabletwo t2 ON t12.idtwo=t2.id
I'll receive an array like this with$stmt->fetch():
Array
(
[id] => 2
[0] => 1
[idone] => 1
[1] => 1
[idtwo] => 2
[2] => 2
[3] => 1
[name] => Test2TwoText
[4] => Test1Text
[5] => 2
[6] => Test2TwoText
)
As you see, the field gets overwritten(the last time by the last element with this name... ;-)), even though the table has an alias.
fetch(PDO::FETCH_ASSOC) as Andrii Filenko recommended returns this:
Array
(
[id] => 2
[idone] => 1
[idtwo] => 2
[name] => Test2TwoText
)
So here the data is even lost, not only just available via the numeric indices.
fetch(PDO::FETCH_NAMED) as Nigel Ren recommended returns this:
Array
(
[id] => Array
(
[0] => 1
[1] => 1
[2] => 2
)
[idone] => 1
[idtwo] => 2
[name] => Array
(
[0] => Test1Text
[1] => Test2TwoText
)
)
Is there a simple and stylish solution for this problem or will I have to do this one by one?
(My DB is available at DB-fiddle if you want to take a look!)
categories Object
(
[_db:categories:private] => db Object
(
[_pdo] => PDO Object
(
)
[_query] => PDOStatement Object
(
[queryString] => SELECT * FROM categories WHERE name_of_category = ?
)
[_error] =>
[_results] => Array
(
[0] => stdClass Object
(
[id] => 10
[name_of_category] => Vedran
[description_of_category] => adsdasdas
[meta_keywords] => sadasdas
[meta_description] => asdasdas
[notes] => sadsadas
[created] => 2016-01-20 08:26:02
)
[1] => stdClass Object
(
[id] => 9
[name_of_category] => VEdran
[description_of_category] => ddddd
[meta_keywords] => qsqddd
[meta_description] => sqdddd
[notes] => sddd
[created] => 2020-01-16 00:00:00
)
)
[_count] => 2
)
[_fields:categories:private] =>
)
Hello. Can someone help me please with this array. I have created in database categories table. I would like to show categories on page where user would be able to manage categories (delete, edit). When i want to show categories from database i get this array in PHP. Now i dont know how to show for example only "name_of_category" on web page. Can someone please help me.
$categories=$ObjVariable->_results;
then use the $categories array to display the values
I am trying to push array data to a MySQL database using foreach(). I'm quite a novice at PHP & mysql, so been working through parsing this data to PHP from an Ajax script, now just need to manipulate the data.
What is the correct syntax to push this data into SQL so that each dataset in the array goes to a seperate row?
i am trying to use foreach, but the complexity is that the array itself can change in size and the second complexity is that the data itself may be refreshed (i.e same id new values on a new day), so I want to build in some intelligence to update info not just append; and also to backup old data to another table.
is this syntax correct?
$sql = "INSERT INTO table1 (col1, col2) VALUES ";
foreach($rows as $i=>$row) {
if ($i>0) {
$sql .= sprintf(",(%s,%s)", $row["col1_value"], $row["col2_value"]);
} else {
$sql .= sprintf("(%s,%s)", $row["col1_value"], $row["col2_value"]);
}
}
mysql_query($sql);
The data in the array is as follows - this is only part of a multidimensional array, but I have figured out how to manipulate the rest of the array to my needs.
The only other thing I need to do is figure out a way to take the coords field and manipulate it as follows
Extract x & y data from coords
Multiple x & y by 600/386
Reverse x & y and take the first digit of each coordinate to create a new value y[1]x[1].
For this I tried just on the first data set, as follows, but I am inexperienced in data handling on PHP. Pretty sure it is wrong.
$testcoords = $_POST['data'][0]['coords'];
list($x,$y) = explode(“:”,str_replace(“’”,“”,$testcoords));
$xtrans = number_format($x*600/386,$decimals=null);
$ytrans = number_format($y*600/386,$decimals=null);
$cont = “C”.$ytrans[0].$xtrans[0]
So to summarize, three questions
How do I transfer data into a table, with rows for each individual dataset in the [data] array?
How do overwrite and archive any existing values in the table rather than simply concatenating?
How do I manipulate one specific string to return a custom variable as defined above?
[data_type] => city
[data] => Array
(
[0] => Array
(
[id] => 16515340
[owner_id] => 3475
[owner] => Player1
[coords] => '268:252
[name] => AC2013
[score] => 11863
[city_type] => castle
[location] => land
)
[1] => Array
(
[id] => 16515335
[owner_id] => 3475
[owner] => Player1
[coords] => '263:252
[name] => AC2013
[score] => 7
[city_type] => castle
[location] => water
)
[2] => Array
(
[id] => 17891610
[owner_id] => 3523
[owner] => Player2
[coords] => '282:273
[name] => City of Repoman9900
[score] => 1978
[city_type] => castle
[location] => water
)
[3] => Array
(
[id] => 10616856
[owner_id] => 73
[owner] => Player2
[coords] => '024:162
[name] => 1killer
[score] => 1308
[city_type] => castle
[location] => water
)
[4] => Array
(
[id] => 10813465
[owner_id] => 2862
[owner] => Player3
[coords] => '025:165
[name] => City of vuvuzea991
[score] => 1091
[city_type] => castle
[location] => land
)
[5] => Array
(
[id] => 17367317
[owner_id] => 84
[owner] => Player4
[coords] => '277:265
[name] => Dreadland
[score] => 776
[city_type] => castle
[location] => water
)
[6] => Array
(
[id] => 2162850
[owner_id] => 2989
[owner] => Player5
[coords] => '162:033
[name] => City of Dinoeyez
[score] => 157
[city_type] => castle
[location] => water
)
[7] => Array
(
[id] => 2818192
[owner_id] => 556
[owner] => Player6
[coords] => '144:043
[name] => City of wildfire123
[score] => 7
[city_type] => castle
[location] => water
)
)
[sender] => Array
(
[world] => Array
(
[id] => 232
[name] => Server 4
[number] => NaN
)
[alliance] => Array
(
[id] => 2
[name] => Alliance2
)
[player] => Array
(
[id] => 98
[name] => SuperUser
)
[browser] => Array
(
[type] => Chrome
[version] => 25.0.1364.160
)
[aix_version] => 1.00
)
)
The problems I see:
foreach($rows as $i=>$row) {
$sql = "INSERT INTO table1 (col1, col2) VALUES "; //reinitialize here.
if ($i>0) { //Why have the if statement, the results of the conditions are the same.
$sql .= sprintf("('%s','%s')", $row["col1_value"], $row["col2_value"]); //add quotation marks for string values, remove the comma.
} else {
$sql .= sprintf("(%s,%s)", $row["col1_value"], $row["col2_value"]);
}
mysql_query($sql); //execute the statement here.
}
Your other questions:
How do overwrite and archive any existing values in the table rather than simply concatenating?
To overwrite you do an update statement, the MySql website gives hints to syntax.
To archive, you will need to create an archive table that is pretty much a duplicate of the table being archived and insert/update that table.
In this context, I am not sure what you mean by concatenation, it does not really apply to databases that are normalized.
How do I manipulate one specific string to return a custom variable as defined above?
Ah gonna skip that one, it is a lot to ask in one post.
I have the models User, Post, Comment and Tag.
User creates Post.
Posts can have multiple Comment and Tag.
Each model has it's own table, so there are tables 'posts', 'comments' and 'tags'. Comments have a foreign key called 'post_id', while Tags have a many_to_many relation table called 'post_tags', in which there are two fields: 'post_id' and 'tag_id'.
I want to get a nested array like below:
Which MySQL queries should I run?
I suppose I need to alter the result with PHP to get my nested array. How?
Thanks a lot for your help :-)
[0] => Array
(
[Post] => Array
(
[id] => 1
[title] => First article
[content] => aaa
[created] => 2008-05-18 00:00:00
)
[Comment] => Array
(
[0] => Array
(
[id] => 1
[post_id] => 1
[author] => Daniel
[email] => dan#example.com
[website] => http://example.com
[comment] => First comment
[created] => 2008-05-18 00:00:00
)
[1] => Array
(
[id] => 2
[post_id] => 1
[author] => Sam
[email] => sam#example.net
[website] => http://example.net
[comment] => Second comment
[created] => 2008-05-18 00:00:00
)
)
[Tag] => Array
(
[0] => Array
(
[id] => 1
[name] => Awesome
)
[1] => Array
(
[id] => 2
[name] => Baking
)
)
)
[1] => Array
(
[Post] => Array
(...
You better of doing 3 queries.
first fetch post (, and left join the user if you need it), and store them like:
$list[$row['post_id']]['Post'] = $row;
then fetch all post-comments and store them as
$list[$row['post_id']]['Comment'][$row['comment_id']] = $row;
then fetch all post-tags
$list[$row['post_id']]['Tags'][$row['tag_id']] = $row;
that far more effective than trying to use a single query,
as a single query going to end up sending the same data multiple times
I was wondering if anyone could help me with selecting information from my table, but grouping the results depending on the order id. I'm sure this is quite simple, but I can't seem to get the code working.
Here's my attempt - which is only showing 1 result, instead of 6:
4 results with orderid 55542
2 results with orderid 55543
SQL:
SELECT *
FROM #__users_orders
WHERE userid = 22
GROUP BY orderid
ORDER BY date DESC
Any help would be appreciated :)
EDIT:
I'd like to acheive this (or something similar)
Array[55542]
(
[0] => stdClass Object
(
[id] => 6
[userid] => 66
[orderid] => 55542
[date] => 2011-08-05 16:30:24
[code] => 121021
[title] => 7 STAR CHICKEN A/KING 71198 1.3KG
[units] => 2
[ctns] =>
)
[1] => stdClass Object
(
[id] => 1
[userid] => 66
[orderid] => 55542
[date] => 2011-08-05 16:06:12
[code] => 302371
[title] => ANCHOVY FILL 730GM
[units] => 2
[ctns] =>
)
[2] => stdClass Object
(
[id] => 6
[userid] => 66
[orderid] => 55542
[date] => 2011-08-05 16:30:24
[code] => 121021
[title] => 7 STAR CHICKEN A/KING 71198 1.3KG
[units] => 2
[ctns] =>
)
[3] => stdClass Object
(
[id] => 1
[userid] => 66
[orderid] => 55542
[date] => 2011-08-05 16:06:12
[code] => 302371
[title] => ANCHOVY FILL 730GM
[units] => 2
[ctns] =>
)
)
Array[55543]
(
[0] => stdClass Object
(
[id] => 6
[userid] => 66
[orderid] => 55543
[date] => 2011-08-05 16:30:24
[code] => 121021
[title] => 7 STAR CHICKEN A/KING 71198 1.3KG
[units] => 2
[ctns] =>
)
[1] => stdClass Object
(
[id] => 1
[userid] => 66
[orderid] => 55543
[date] => 2011-08-05 16:06:12
[code] => 302371
[title] => ANCHOVY FILL 730GM
[units] => 2
[ctns] =>
)
)
SELECT *
FROM #__users_orders
WHERE userid = 22
ORDER BY orderid DESC
Just select your items like this and create your object/array hierarchy in the frontend by iterating over the results and creating a new array for every new orderid that comes by.
SELECT orderid, COUNT(*)
FROM #__users_orders
WHERE userid = 22
GROUP BY orderid
ORDER BY date DESC
Normally, you have to use an aggregate (eg COUNT, SUM) and GROUP BY matched. So that columns in the SELECT but not in the COUNT or SUM are in the GROUP BY
Only MySQL allows you to not follow this rule. Other DB engines would give an error.
the query seems ok, maybe your extracting the results the wrong way
SELECT * FROM table GROUP BY field1;
should return same number of rows than
SELECT field1, field2 FROM table GROUP BY field1;
but different number than
SELECT * FROM table;
You should not select "*" in this query.
When you group by "some columns". You can only select "some columns" or some_aggregate_function(other columns).
e.g. If you want to get the aggregate ordersize and latest date for each order id, you would do something like -
SELECT orderid, sum(ordersize), max(date) FROM #__users_orders WHERE userid = 22 GROUP BY orderid ORDER BY max(date) DESC