show mysql average of the last 14 days in a c# application - mysql

I have a mysql table with the columns ID, name, gold and timestamp.
This table shows with the following statement the average of the gold of the respective item(name). But now the database is already filled with 90k entries and the average should only be limited to 2 weeks. Here is the code:
`
private DataTable GetAverageGold()
{
var dtAverageGold = new DataTable();
var percentageBuy = double.TryParse(textBox1.Text.Replace("%", string.Empty), out var sell) ? sell / 100 : 0.02;
using (_con = GetMySqlConnection())
{
using (var cmd = new MySqlCommand(
"SELECT name AS name, FORMAT(GROUP_CONCAT(gold ORDER BY id DESC), 'de_DE') AS 'MOST RECENT', FORMAT(ROUND(AVG(gold) - AVG(gold) * " +
percentageBuy.ToString(CultureInfo.InvariantCulture).Replace(",", ".") +
"), 'de_DE') AS Einkaufspreis, FORMAT(ROUND(AVG(gold)),'de_DE') AS Durchschnitt, ROUND((AVG(gold) - GROUP_CONCAT(gold ORDER BY id DESC)) / GROUP_CONCAT(gold ORDER BY id DESC) * 100,2) AS 'profit in %' FROM items GROUP BY name ORDER BY Name",
_con))
{
try
{
_con.Open();
var reader =
cmd.ExecuteReader();
dtAverageGold.Load(reader);
}
catch (MySqlException ex)
{
MessageBox.Show(ex.ToString(), "Error in: GetAverageGold", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
finally
{
_con.Close();
}
}
}
return dtAverageGold;
}
`
I tried "WHERE timestamp <= NOW() + INTERVAL 14 DAY GROUP BY name ORDER BY name" at the end of the statement. but it did not help. The syntax seems to be correct, as I get no error, but the average still refers to all entries

You were thinking along the right lines but it should have been -
WHERE timestamp >= NOW() - INTERVAL 14 DAY
or
WHERE timestamp >= CURRENT_DATE - INTERVAL 14 DAY

Related

MySQL using BETWEEN not returning anything?

I am trying to get all rows from my MySQL database that are from the last week and also have the right company_id. I don't understand why this isn't returning any data, as there are no errors.
A screenshot of the database:
My code:
// Create Calendar and Date objects
Calendar calendar = Calendar.getInstance();
java.sql.Date date = new java.sql.Date(calendar.getTime().getTime());
// Get all datapoints from last week from this company's id
query = "SELECT * FROM survey_data WHERE (company_id = ?) AND (date_entered BETWEEN ? + interval ? day AND ? + interval ? day)";
preparedStatement = conn.prepareStatement(query);
preparedStatement.setString(1, companyId);
preparedStatement.setDate(2, date);
preparedStatement.setInt(3, -Calendar.DAY_OF_WEEK - 6);
preparedStatement.setDate(4, date);
preparedStatement.setInt(5, -Calendar.DAY_OF_WEEK);
resultSet = preparedStatement.executeQuery();

Query database for Current Week Results [duplicate]

I have table temp with structure on sqlfiddle:
id(int 11 primary key)
name(varchar 100)
name2(varchar 100)
date(datetime)
I would like get record on this week, example if now 21.11.2013 i would like all rows on 18.11.2013 to 24.11.2013(on week)
Now I see next algorithm:
obtain weekday
calculate how many days ago was Monday
calculate the date Monday
calculate future date Sunday
make a request on date
Tell me please, is exist a shorter algorithm (preferably in the query MySQL)?
ADD Question is: Why this query select record on date 17.11.2013(Sunday) - 23.11.2013(Saturday) and how get records on date 18.11.2013(Monday) - 24.11.2013(Sunday) ?
query:
select * from temp
where yearweek(`date`) = yearweek(curdate())
Thanks!
Use YEARWEEK():
SELECT *
FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1)
Use YEARWEEK. If you use WEEKOFYEAR you will get records of previous years also.
SELECT id, name, date
FROM table
WHERE YEARWEEK(date)=YEARWEEK(NOW());
For selecting records of day, week and month use this way:
function my_func($time, $your_date) {
if ($time == 'today') {
$timeSQL = ' Date($your_date)= CURDATE()';
}
if ($time == 'week') {
$timeSQL = ' YEARWEEK($your_date)= YEARWEEK(CURDATE())';
}
if ($time == 'month') {
$timeSQL = ' Year($your_date)=Year(CURDATE()) AND Month(`your_date`)= Month(CURDATE())';
}
$Sql = "SELECT * FROM your_table WHERE ".$timeSQL
return $Result = $this->db->query($Sql)->result_array();
}
You can do it by following method
SELECT DATE_FORMAT("2017-06-15", "%U");
Get number of week (From 00 to 53 )
Where (Sunday 1st day and Monday last day of week)
May be useful for you.
example:
SELECT DISTINCT DATE_FORMAT('dates', '%U') AS weekdays FROM table_name;
The short solution would be this:
SELECT * FROM my_table WHERE DATE_FORMAT("2021-08-19 15:40:33", "%U") = WEEK(CURDATE());

MySQL - DATE_ADD month interval by each month

I have written a function below to give me the number of jobs an employee has done in a particular 30 day period (each ID in the 'jobs column' of the table represents 1 job).
the function work fine if I only want to look back 4 week. the problem however is that I want the count to start at the beginning of each month. for example, if a person views the records on the 10th December 2013 I need the records to show all the work for December (but not the records for the preceding 30 days).
Below is my function:
$interval_1month = 'interval 4 WEEK';
function statsHowMuchWorkDoneByStaff ($staff_id, $timeInterval)
{
global $dbc;
$select = " SELECT
COUNT(job_id) AS totalnumberWork ";
$from = " FROM
staffwork
";
$where = " WHERE
staff_id = $staff_id
AND
FROM_UNIXTIME(entrytime) >= now() - $timeInterval";
$query = $select.$from. $where;
$result = mysqli_query ($dbc, $query)
or trigger_error("Query: $query\n<br />MySQL Error: " . mysqli_error($dbc));
if(mysqli_num_rows($result))
{
$row = mysqli_fetch_array ($result, MYSQLI_ASSOC);
$result = safe_output($row['totalnumbernewcontacts']) ;
return $result ;
}
else
{
return false;
}
}
Any advise on how to proceed would be greatly appreciated.
UPDATE: here is my datatable:
CREATE TABLE staffwork(
staff_id MEDIUMINT UNSIGNED NOT NULL,
job_id MEDIUMINT UNSIGNED NOT NULL,
data_table VARCHAR (65) NOT NULL,
entrytime int(11) NOT NULL,
INDEX message (staff_id)
);
If I understand correctly and you want to calculate COUNT(job_id) for a specific month by supplying any date of that month as a parameter, then you can do it this way
SELECT COUNT(job_id) total
FROM staffwork
WHERE staff_id = 1
AND entrytime >= UNIX_TIMESTAMP(LAST_DAY('2013-12-10') + INTERVAL 1 DAY - INTERVAL 1 MONTH)
AND entrytime < UNIX_TIMESTAMP(LAST_DAY('2013-12-10') + INTERVAL 1 DAY)
Note: This query is index friendly because it doesn't convert entrytime to datetime but rather convert range values (which are constants for the query) to unix time. Make sure that you have indices on entrytime and staff_id to be able to take advantage of that.
Here is SQLFiddle demo
And while you're at it consider to learn and use prepared statements instead of interpolating query strings leaving your code vulnerable for sql injections.
That being said your php function might look like this
function statsWorkDoneByStaffMember($staff_id, $month) {
global $dbc;
$sql = "
SELECT COUNT(job_id) total
FROM staffwork
WHERE staff_id = ?
AND entrytime >= UNIX_TIMESTAMP(LAST_DAY(?) + INTERVAL 1 DAY - INTERVAL 1 MONTH)
AND entrytime < UNIX_TIMESTAMP(LAST_DAY(?) + INTERVAL 1 DAY)
";
$stmt = $dbc->prepare($sql);
if (!$stmt) {
trigger_error('Prepare failed: ' . $dbc->error);
}
$stmt->bind_param('iss', $staff_id, $month, $month);
if(!$stmt->execute()) {
trigger_error('Execute failed: ' . $dbc->error);
}
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
return $result;
}
Sample usage:
$dbc = new mysqli('localhost', 'user', 'password', 'dbname');
$staff_id = 1;
//Get the number of job_id for the current month
$total = statsWorkDoneByStaffMember($staff_id, date('Y-m-d'));
//Get the number of job_id for a specific month
$total = statsWorkDoneByStaffMember($staff_id, '2013-07-01');

MySQL: How to select records for this week?

I have table temp with structure on sqlfiddle:
id(int 11 primary key)
name(varchar 100)
name2(varchar 100)
date(datetime)
I would like get record on this week, example if now 21.11.2013 i would like all rows on 18.11.2013 to 24.11.2013(on week)
Now I see next algorithm:
obtain weekday
calculate how many days ago was Monday
calculate the date Monday
calculate future date Sunday
make a request on date
Tell me please, is exist a shorter algorithm (preferably in the query MySQL)?
ADD Question is: Why this query select record on date 17.11.2013(Sunday) - 23.11.2013(Saturday) and how get records on date 18.11.2013(Monday) - 24.11.2013(Sunday) ?
query:
select * from temp
where yearweek(`date`) = yearweek(curdate())
Thanks!
Use YEARWEEK():
SELECT *
FROM your_table
WHERE YEARWEEK(`date`, 1) = YEARWEEK(CURDATE(), 1)
Use YEARWEEK. If you use WEEKOFYEAR you will get records of previous years also.
SELECT id, name, date
FROM table
WHERE YEARWEEK(date)=YEARWEEK(NOW());
For selecting records of day, week and month use this way:
function my_func($time, $your_date) {
if ($time == 'today') {
$timeSQL = ' Date($your_date)= CURDATE()';
}
if ($time == 'week') {
$timeSQL = ' YEARWEEK($your_date)= YEARWEEK(CURDATE())';
}
if ($time == 'month') {
$timeSQL = ' Year($your_date)=Year(CURDATE()) AND Month(`your_date`)= Month(CURDATE())';
}
$Sql = "SELECT * FROM your_table WHERE ".$timeSQL
return $Result = $this->db->query($Sql)->result_array();
}
You can do it by following method
SELECT DATE_FORMAT("2017-06-15", "%U");
Get number of week (From 00 to 53 )
Where (Sunday 1st day and Monday last day of week)
May be useful for you.
example:
SELECT DISTINCT DATE_FORMAT('dates', '%U') AS weekdays FROM table_name;
The short solution would be this:
SELECT * FROM my_table WHERE DATE_FORMAT("2021-08-19 15:40:33", "%U") = WEEK(CURDATE());

MySQL: INTERVAL problems

I'm looking for a one week interval, but any thing under 6 gives me:
timeIn > DATE_SUB(NOW(), INTERVAL 1 WEEK)
Error: Invalid attempt to Read when reader is closed.
timeIn > DATE_SUB(NOW(), INTERVAL 6 WEEK) //6 or anything above 6 and the query works
Error: Invalid attempt to Read when reader is closed.
Here's how I'm executing the query(this works, but when I change the INTERVAL from 6 to anything less I get the reader is closed error):
string sql = "SELECT rooms.building, rooms.room, " +
"users.FirstName, users.LastName, users.adUname, " +
"ingressegresslogs.timeIn, ingressegresslogs.timeOut, rooms.Id " +
"FROM rooms, users, ingressegresslogs " +
"WHERE ingressegresslogs.RoomId = rooms.Id " +
"AND ingressegresslogs.timeIn > DATE_SUB(NOW(), INTERVAL 6 WEEK) "
"AND ingressegresslogs.UserId = users.id " +
"ORDER BY rooms.Id ASC, ingressegresslogs.timeIn ASC";
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader rdr = cmd.ExecuteReader();
EDIT: This query works from the mysql command line for and INTERVAL 1 WEEK just not in the C# code. 428 rows with data are returned
Here is the reader code, which may be where the problem is.
MySqlCommand cmd = new MySqlCommand(sql, conn);
MySqlDataReader rdr = cmd.ExecuteReader();
if (!rdr.HasRows)
{
rdr.Close();
// EventLog.WriteEntry("IEReporter", "Database returned nothing", EventLogEntryType.Error, 234);
}
while (rdr.Read())
{
try
{
IELog queryResult = new IELog();
queryResult.RoomID = rdr.GetString("Id");
queryResult.FirstName = rdr.GetString("FirstName");
queryResult.LastName = rdr.GetString("LastName");
queryResult.ADUname = rdr.GetString("ADUname");
queryResult.Building = rdr.GetString("Building");
queryResult.Room = rdr.GetString("room");
queryResult.Ingresstime = rdr.GetDateTime ("timeIn");
// timeOut might be null
if (Convert.IsDBNull(rdr["timeOut"]))
{
queryResult.Egresstime = new DateTime(1111, 1, 11);
}
else
{
queryResult.Egresstime = rdr.GetDateTime("timeOut");
}
queryResultList.Add(queryResult);
}
catch (Exception ex)
{
Console.WriteLine("LogDAO build list: " + ex);
}
}
// Count rows
//Console.WriteLine("Row Count: {0}", queryResultList.Count);
rdr.Close();
return queryResultList;
Seeing the code you posted, you probably want to return immediately after you determine there are no rows.
if (!rdr.HasRows)
{
rdr.Close();
// EventLog.WriteEntry("IEReporter", "Database returned nothing", EventLogEntryType.Error, 234);
return; // do this, or otherwise skip the read below
}
The SQL works for me:
mysql> select DATE_SUB(NOW(), INTERVAL 1 WEEK);
+----------------------------------+
| DATE_SUB(NOW(), INTERVAL 1 WEEK) |
+----------------------------------+
| 2011-07-07 01:16:50 |
+----------------------------------+
Could it be your problem is that you are getting no rows returned, and that's why the reader is exploding?