Why when caching queries are relationships not cached? - php

Throughout querying my database with the queries as the one below;
Model::with('first','second','third','fouth','fiveth')
->orderBy('title')
->remember(2,'domain.query')
->get()
The overall query gets cached etc, but why don't the relationships that I attach to the query. Would I have to do a join on the models etc to accomplish everything getting cached etc?
Queries made in Clockwork:
SELECT * FROM `first_table` WHERE `first_table`.`id` in ('2', '4', '3')
SELECT * FROM `second_table` WHERE `second_table`.`id` in ('2', '5', '1', '4')
SELECT * FROM `third_table` WHERE `third_table`.`id` in ('2', '5', '1', '4')
SELECT * FROM `fouth_table` WHERE `fouth_table`.`id` in ('2', '5', '1', '4')
SELECT * FROM `fiveth_table` WHERE `fiveth_table`.`id` in ('2', '5', '1', '4')

"Why" is somewhat of a broad question, it is a design decision made by the framework author. The way to get around it, though it's not very pretty code, is to use eager load constraints:
Model::with([
'first' => function($q) { $q->remember(...); },
'second' => ...
])->remember(...)->get();

Related

using mysql (too much data) to get statics about activity of different users

I'm trying to figure out how to make a query to get the data of top then users of some list ...later I will use php to statics and graphs but what I want is to get the sum of every single user but I find it difficult because in one month one single user can make many registers on database and I want to manage it and then get the top ten of users who have more activities (on this case with more quantity per month).
Example
user_id quantity date kind
user1 23 17/03/18 free
user1 3 17/03/18 charge
user2 5 17/03/18 free
user2 5 17/03/18 free
user2 8 18/03/18 free
user3 9 19/03/18 free
user3 1 20/03/18 free
user3 1 20/03/18 charge
user3 3 20/03/18 charge
user3 5 20/03/18 charge
You can store arrays in a database by serializing them, inserting them into the database, and then unserializing them when you retrieve from the database.
Arrays can be multidimensional in PHP, that means that arrays can store arrays and so on. Also arrays can be relational, meaning that you can store values and give an identifier ('key') to each value.
Knowing that, you can do stuff like:
$con = new mysqli($host, $username, $password, $db_name);
$stmt = $con->prepare('SELECT * FROM users WHERE user_id=?;');
$stmt->bind_param('s', $id);
$stmt->execute();
$result = $stmt->get_result()->fetch_array();
if ($array_data = unserialize($result['data'])) {
echo 'The quantity related to ', $result['name'], ' is ', $array_data['quantity'];
} else {
echo 'It seems that there\'s nothing related to ', $result['name'], ' yet. Adding a field now.';
$array_data = array(
'quantity' => 23,
'date' => date('l jS \of F Y h:i:s A'),
'kind' => 'free'
);
}
$array_data = serialize($array_data);
$stmt2 = $con->prepare('UPDATE users SET data=? WHERE user_id=?;');
$stmt2->bind_param('ss', $array_data, $id);
$stmt2->execute();
The example above is pretty abstract, but you can get a grasp of what you can do with serialization and arrays. MySQL does not have an "array" type, but you can use serialize and unserialize with almost all objects in PHP to store them in databases.
Note that the serialized fields' type in MySQL should be "BLOB".
I think that a simple count query will do the job that you want. Something like this:
Select user_id, sum(quantity) as activity-count
From ActivityTable
Group By user_id
Where kind = something; # (Optional)
I don't have so much information here about your database, so all I got is a direction for your target task.
A little test that I have run:
Table:
userid, quantity, date, kind
'0', '3', '2017-03-18', 'charge'
'0', '23', '2017-03-18', 'free'
'0', '3', '2018-03-18', 'charge'
'2', '5', '2017-03-18', 'charge'
'2', '5', '2017-03-18', 'free'
'2', '8', '2018-03-18', 'free'
'3', '9', '2019-03-18', 'free'
'3', '1', '2020-03-18', 'charge'
'3', '1', '2020-03-18', 'free'
'3', '3', '2021-03-18', 'charge'
'3', '3', '2022-03-18', 'charge'
Query:
Select userid, month(date) as 'month', sum(quantity) as activity_count
From table1
Group By userid, month(date)
Result:
userid, month, activity_count
'0', '3', '29'
'2', '3', '18'
'3', '3', '17'
This query should return you the list of top 10 users for the month:
select user_id, SUM(quantity) as qty
from table_name
group by user_id
where MONTH(CURDATE())= MONTH(date) AND
YEAR(CURRENT_DATE()) = YEAR(date)
Order by qty DESC
LIMIT 0,10;

How can i remove the oldest entries in my SQL result?

I want to get only the last reports, for all items but only the most recent report for each item_id.
Here is my current solution:
SELECT distinct * FROM t.reports ORDER BY created DESC LIMIT 100
My table consists of the following columns:
id | user | item_id | created
'2', '1', '2643', '2017-06-13 16:28:34'
'3', '1', '19333', '2017-06-13 19:26:56'
'4', '1', '19333', '2017-06-13 19:29:24'
'5', '1', '1319', '2017-06-13 19:29:56'
'6', '1', '1319', '2017-06-13 19:30:16'
'7', '1', '1319', '2017-06-13 19:30:17'
'8', '1', '1319', '2017-06-13 19:30:18'
'9', '1', '1319', '2017-06-13 19:30:25'
'10','1', '1319', '2017-06-13 19:31:51'
I want no duplicate item_ids AND only the most recent entry for that item.
BUT i also want ALL reports, but no duplicate item reports!
EXAMPLE:
i expect that when i execute my query, i only get row 2,4 and 10 returned.
Try this:
select a.id,a.user,a.item_id,a.created
from reports as a
where a.created=(select max(created)
from reports as b
where a.item_id=b.item_id)
Try This let me know if this works.
SELECT *
FROM t.reports
where item_id in (
select distinct item_id
from t.reports
)
ORDER BY updated DESC
LIMIT 100
Try with this I have tested it on my test database:
SELECT DISTINCT item_id, MAX(created), id, user
FROM `t.reports`
GROUP BY item_id
ORDER BY MAX(created) DESC
You can use group by :
SELECT * FROM t.reports WHERE created IN (SELECT max(created) FROM t.reports)
GROUP BY item_id
LIMIT 100

CI Is there a way to query custom order_by

Is it possible to customize the order_by query in MySQL or in CI ? Such as I want my column to be ordered by ('1', '11', '4', '2', '21', '3', '5', '7') So if I query it as ASC the result will show in the order of my customized order.
If it is not possible, what is the best workaround to get these order ? Hoping for a simple solution just using the MySQL query.
All answers and suggestions are greatly welcomed. Thanks.
Try this one.
$this -> db -> order_by('FIELD ( table.id, 1, 11, 4,2,21,3,5,7 )');
link
Pure Mysql answer is yes you can order a field by a set list with the MYSQL FIELD() function
SELECT *
FROM mytable
WHERE id IN ('1', '11', '4', '2', '21', '3', '5', '7')
ORDER BY FIELD(id, '1', '11', '4', '2', '21', '3', '5', '7')

Creating nested json object using php mysql

Let's say that I have created two tables in my database:
`INSERT INTO `months` (`month_id`, `month_name`) VALUES ('1', 'January');`
and
`INSERT INTO `weeks_and_days` (`week_id`, `week_nr`, `day_nr`) VALUES ('1', '1', '1'), ('2', '1', '2'), ('3', '1', '3'), ('4', '1', '4'), ('5', '1', '5'), ('6', '1', '6'), ('7', '1', '7');`
What should be the correct PHP and SQL code to get exactly the following nested JSON:
{
"month_name": "Yanuary",
"week_nr": {
"1": [{
"day_nr": [1, 2, 3, 4, 5, 6, 7]
}]
}
}
I read a couple of answers and tried to apply them in my code, but I faild. I need some simple formula as I am quite new in programming.
Instead of directly generating the json off MySQL, you should write the queries to get different values and put them together to generate json, e.g.:
SELECT month_name
FROM months
WHERE month_id = 1;
SELECT week_nr, GROUP_CONCAT(day_nr)
FROM weeks_and_days
GROUP BY week_nr;
First query gives you the month name and second query gives you the week/day info.
Please note that weeks_and_days table does not have any column for month_id, it needs one to map to months table (via foreign key).

I need to change a complex MYSQL query in to a view or views

I have a query that creates a rolling sum and subtracts that from a sum total. I have the query working in the SQL window, but I need some help changing it in to a view or table that I can call from a PHP so I can use the results in building a graph.
This query builds the basis for a burndown report used in project management so it is very handy.
When I try to create a view out it I get multiple errors with joins and variables not being allowed in a view. I am kind of a mysql newbie and I am beating my head on this one.
Here is the SQL query:
SELECT
taskid,
projectid,
esthours,
actualhours,
eview.SE As TotalHours,
(#EST:=#EST - esthours) as ESTI,
(eview.SE + #EST) as Estimated,
(#EST2:=#EST2 - actualhours) as AC,
(eview.SE + #EST2) as Actual
from
tbltasks,
eview
JOIN
(SELECT #EST:=0) EE
JOIN
(SELECT #EST2:=0) E2;
Here is a sample of the results.
taskid, projectid, esthours, actualhours, TotalHours, ESTI,Estimated, AC, Actual
'1021', '2', '4', '3', '20', '-4', '16', '-3', '17'
'1022', '2', '3', '3', '20', '-7', '13', '-6', '14'
'1023', '2', '2', '4', '20', '-9', '11', '-10', '10'

Categories