Creating nested json object using php mysql - php

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).

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;

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')

how to display attendance report based on roll number and i want everything to be dynamic [duplicate]

This question already has an answer here:
MySQL pivot row into dynamic number of columns
(1 answer)
Closed 5 years ago.
I am working on Classes management project. Everything is done successfully but only stuck with attendance report work.
i want result like this
My table structure:
CREATE TABLE mp_attendence (atid int, atdisplayname varchar(9), atroll varchar(9), atstatus varchar(9), atdate date, atbatch varchar(9)) ;
INSERT INTO mp_attendence (atid, atdisplayname, atroll, atstatus, atdate, atbatch) VALUES (1, 'lavkush', '1', 'absent', '2017-03-01', 'p1'), (2, 'dhanji', '2', 'present', '2017-03-01', 'p1'), (3, 'lavkush', '1', 'present', '2017-03-02', 'p1'), (4, 'dhanji', '2', 'present', '2017-03-02', 'p1'), (5, 'lavkush', '1', 'present', '2017-03-04', 'p1'), (6, 'dhanji', '2', 'absent', '2017-03-04', 'p1'), (7, 'lavkush', '1', 'present', '2017-03-05', 'p1'), (8, 'dhanji', '2', 'absent', '2017-03-05', 'p1') ;
SET #sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'(case when atstatus = ''',
atstatus,
''' then (atstatus) end) AS ',
replace (DATE_FORMAT(atdate, '%d %M %Y'), ' ', '')
)
) INTO #sql
from mp_attendence;
SET #sql = CONCAT('SELECT atdisplayname, atroll, ', #sql, ' from mp_attendence
group by atroll');
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
From above query i achieve this result but i want to combine same dates like 1st march result should be in same row.
result achieved

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'

Why when caching queries are relationships not cached?

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();

Categories