I'm struggling on how to write this query and cant quite find an answer to help me with my case.
Consider the following table:
-----------------------------------------------
| ID | Value1 | Value2 | Value3 | Date |
-----------------------------------------------
| 1 | 10 | 23 | 30 | 2015-01-01 |
-----------------------------------------------
| 1 | 11 | 33 | 40 | 2015-02-01 |
-----------------------------------------------
| 2 | 26 | 93 | 20 | 2015-01-01 |
-----------------------------------------------
| 2 | 11 | 33 | 50 | 2015-02-01 |
-----------------------------------------------
I want to retrieve the average value of Value1 where the Date is 2015-01-01
I thought that
SELECT AVG(PAM_1) FROM MyTable WHERE DATE = 2015-01-01
would work but of course it does not. I'm aware that I probably need to use HAVING but I'm being confused if I must also use GROUP BY and if do I need the AS (something) part.
EDIT
The problem was not related to the query. I was supplying the date trough a variable as such:
$sth = $db->prepare("SELECT AVG(Value1) FROM MyTable WHERE DATE = $date");
Which is not possible to do with prepared statements.
Your query is basically fine. Your date constant is not. Dates constants should be enclosed in single quotes:
SELECT AVG(PAM_1)
FROM MyTable
WHERE DATE = '2015-01-01';
If the date could have a time component, then the following is the best way to handle this:
SELECT AVG(PAM_1)
FROM MyTable
WHERE DATE >= '2015-01-01' AND DATE < '2015-01-02';
Related
I have a table prices with where I store more times in a day more values referred to a customer like this:
Table prices:
| id | customer_id | value_1 | value_2 | value_3 | created_at |
-------------------------------------------------------------------------
| 1 | 10 | 12345 | 122 | 10 | 2021-08-11 10:12:40 |
| 2 | 10 | 22222 | 222 | 22 | 2021-08-11 23:56:20 |
| 3 | 12 | 44444 | 444 | 44 | 2021-08-12 08:12:10 |
| 4 | 10 | 55555 | 555 | 55 | 2021-08-13 14:11:20 |
| 5 | 10 | 66666 | 666 | 66 | 2021-08-13 15:15:30 |
| 6 | 10 | 77777 | 777 | 77 | 2021-08-13 16:12:50 |
I have some filters on that table to retrieve only records with date greater than X and/or lower than Y, sort records by value_1 or value_2, etc...
With that filters I have to take only 1 record for each day of a customer specified.
I'm able to get the record with the highest value_1 for example, by using sql function max() and group by date.
// Init query
$query = Price::query();
// Take the greatest value of value1
$query = $query->selectRaw(
'max(value_1) as highest_value_1, ' .
'date(created_at) as date'
);
// If defined, add a greater or equals
if ($from) $query->where("created_at", ">=", $from);
// If defined add a lower or equals
if ($to) $query->where("created_at", "<=", $to);
// Get results for current customer only, grupping by date and ordering it
$query = $query->where('customer_id', $id)->groupBy('date')
->orderBy('date', 'DESC');
// Fetch records
$records = $query->get();
But now I would like to have only the last record for each day of a customer specified.
I need an eloquent/sql solution because the date range to search may be large and the table has a lot of records.
How can I archive that?
Thanks
Not a complete solution (no customer filter nor laravel use), but I would use something like that in pure sql :
SELECT
CONCAT(EXTRACT(YEAR_MONTH FROM created_at),EXTRACT(DAY FROM created_at)) AS day,
MAX(created_at)
FROM mytable
GROUP BY day;
Of course, you may use other function to group by day (like string regexp or substr).
First, I have query like this:
SELECT
a.idpeg,
a.tanggal,
a.jam_masuk,
a.jam_pulang,
a.mode_absen
FROM
`tp_rekap_2018-01` a
WHERE
id_opd = '3'
AND periode = '2018-01'
And the result is:
+------+------------+-----------+------------+-----------+
|idpeg | tanggal | jam_masuk | jam_pulang | mode_absen|
+------+------------+-----------+------------+-----------+
|001 | 2018-01-01 | 07:01:01 | 14:01:01 | 1 |
|001 | 2018-01-02 | 08:01:01 | 15:01:01 | 1 |
|001 | 2018-01-03 | 09:01:01 | NULL | 1 |
|002 | 2018-01-01 | 10:01:01 | 16:01:01 | 1 |
|003 | 2018-01-01 | 11:01:01 | 17:01:01 | 1 |
|003 | 2018-01-02 | 12:01:01 | 18:01:01 | 1 |
+------+------------+-----------+------------+-----------+
my question is what I have to do when I want to show result of query with this format of table
Friend of mine suggest me to use the 'for' to loop the date/day and I was successfully generate day from day 1 to the last day of the month. But I can't get the loop script of date/day based on 'idpeg' from the left.
thx b4.
The correct way, i think is using PIVOTS. https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
There are many ways to do it. I can tell you what will be good solution in my opinion.
First of all, looks like you need some user system (make some user object in your PHP script and file or record in the database representing the user).
Then add the date records respectively to user id:
for (i = 0; i < idpeg.size; ++i)
user[a.idpeg[i]] = a.tanggal[i]
Then just use loop to print user data in columns as you did before.
Example my_table
ID | Name | Date
--------------------------
12 | John | 123456789
13 | Mike | 987654321
...
29 | Rick | 123498765
30 | Adam | 987651234
show output result like this
Month | Count
--------------------------
3 | 5 |
6 | 8 |
How can I do this with PHP?
You can do this using MySQL Query as below.
SELECT MONTH(FROM_UNIXTIME(`Date`)) `Month`
,COUNT(ID)
FROM my_table
GROUP BY `Month`;
Since post tagged codeigniter
This is codeigniter way:
$query = $this->db->select("month(from_unixtime(`Date`)) as `month`, count(1) as `count`",FALSE)
->group_by("month");
->get("your_table");
I am creating a graph where I can get the total views everyday for a certain range, or as long it goes back.
The problem I am having is to fill a default number of 0 when no views has been made for a certain day, some days there may be absolutely no views in a day so I need MySQL to return a default of 0 when none is found - I have no idea how to do this.
This is the query I use to get the total views a day:
SELECT DATE(FROM_UNIXTIME(v.date)) AS date_views,
COUNT(v.view_id) AS total_views
FROM
(
views v
)
GROUP BY date_views
ORDER BY v.date DESC
My results return this:
+------------+-------------+
| date_views | total_views |
+------------+-------------+
| 2012-10-17 | 2 |
| 2012-10-15 | 5 |
| 2012-10-14 | 1 |
| 2012-10-10 | 7 |
+------------+-------------+
However there are missing days that I want to return 0 for it, as 2012-10-16, 2012-10-11, 2012-10-12, 2012-10-13 is not included.
So, for example:
+------------+-------------+
| date_views | total_views |
+------------+-------------+
| 2012-10-17 | 2 |
| 2012-10-16 | 0 |
| 2012-10-15 | 5 |
| 2012-10-14 | 1 |
| 2012-10-13 | 0 |
| 2012-10-12 | 0 |
| 2012-10-11 | 0 |
| 2012-10-10 | 7 |
+------------+-------------+
Would be returned.
How would this be approached?
When I did this a couple of years ago I created an empty array with the date as key and the default value 0. Then I simply looped through the result att changed the value for those dates I had.
for each($result as $row){
$date_stats_array[$row['date']] = $row['value'];
}
In situations like this I create a temporary table which I fill with all the dates you want. After that, you can use that table to join your original query against.
To fill the table you can use this procedure:
DROP PROCEDURE IF EXISTS filldates;
DELIMITER |
CREATE PROCEDURE filldates(dateStart DATE, dateEnd DATE)
BEGIN
WHILE dateStart <= dateEnd DO
INSERT INTO tablename (_date) VALUES (dateStart);
SET dateStart = date_add(dateStart, INTERVAL 1 DAY);
END WHILE;
END;
|
DELIMITER ;
CALL filldates('2011-01-01','2011-12-31');
Courtesy of https://stackoverflow.com/a/10132142/375087
I need to write a query to retrieve values from two columns using mysql table
My table has the following strucutre
| ID | user_id | datetime | message |
| 1 | 21 | 2012-05-10 04:13:01 | message1 |
| 2 | 07 | 2012-05-10 04:17:51 | message2 |
| 3 | 21 | 2012-05-11 04:21:51 | message3 |
| 4 | 21 | 2012-05-11 04:43:51 | message4 |
| 5 | 07 | 2012-05-11 04:21:51 | message5 |
| 5 | 21 | 2012-05-11 04:43:51 | message6 |
i wrote the below query
$query="SELECT MAX(datetime) FROM messages where user_id=21 and date=2012-05-11";
but i am not getting latest record from table iam getting null value
help us
$query="SELECT MAX(datetime) FROM messages where user_id=21 and date LIKE '2012-05-11%'";
You should use DATE(date) to get date of timestamp. MySQL function DATE() extracts only date without hours, minutes and seconds.
Here is your query:
SELECT MAX(datetime)
FROM messages
WHERE user_id = 21 AND DATE(date) = '2012-05-11'
Have you tried the following?
$query="SELECT MAX(datetime) FROM messages where user_id=21";
Update:
In your question, you didn't specify if you wanted to retrieve last record for a certain date. If you do, you'd need to use MySQL's date function.
Are you looking for the most recent record? You can get this with a subquery:
$query = "SELECT * FROM messages WHERE datetime = (SELECT MAX(datetime) FROM messages)";
Your query asks for ".....date=2012-05-11";" but your table does not have the field named date? did you mean datetime? if so, you may want to try ".....datetime like '2012-05-11%'";