SELECT count from multiple tables between 2 dates with BIG DATA - php

I have multiple tables (same column structures) which I want to have the count rows between 2 date ranges. Right now it gives me all records from each table. Each table have around 700K records, which makes it also slow to search through.
I'm not getting the right query for this.
The below query is what I have so far.
$monday = '2018-01-15';
$tuesday = '2018-01-16';
SELECT count(datetime) FROM uptime_m1 WHERE datetime
BETWEEN '$monday' and'$tuesday' and status = 'idle'
UNION ALL
SELECT (datetime) FROM uptime_m2 WHERE datetime
BETWEEN '$monday' and'$tuesday' and status = 'idle';
PHP CODE:
if ($result = $mysqli->query("
SELECT count(datetime) FROM uptime_m1 WHERE datetime
BETWEEN '$monday' and'$tuesday' and status = 'idle'
UNION ALL
SELECT (datetime) FROM uptime_m2 WHERE datetime
BETWEEN '$monday' and'$tuesday' and status = 'idle';
")) {
$row_cnt = $result->num_rows;
$count_m1_idle_monday = $row_cnt;
$result->close();
}

You can use a subrequest to count each table and sum the result.
select
(select count(*) from uptime_m1
where datetime between '$monday' and '$tuesday' and status = 'idle')
+ (select count(*) from uptime_m2
where datetime between '$monday' and '$tuesday' and status = 'idle')
as nbrows;

Related

Fetch rows from mysql table if a condition satisfies in php

I have a table like this
my table is here
I need to fetch the table such that the valid_from date is less than the the date which I have(date cannot be current date).
For example. If my date is 02-04-2015, I should get the row with id 120.
Plz help me to do this in php
Please try below quewry :
$input_date = "02-04-2015";
$your_date = date("Y-m-d",strtotime($input_date));
$sql = "SELECT * FROM `table_name` where DATE(validFrom) < '".$your_date."'";
as per your example
SELECT * FROM `your_table_name` where validFrom < '02-04-2015' order by validFrom desc LIMIT 1
or
SELECT * FROM `your_table_name` where validFrom < '02-04-2015' order by validFrom asc LIMIT 1
set order by as per your expectation of output
here you want to pass date as per your date format

Mysql IFNULL working only once in a multiple SELECT query

I'm trying to build a month graphic using a MySQL query. I'm checking how many rows there are in a table for each month in a single query using the UNION command. Example with 3 months bellow:
$query =
"SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 1), 0) AS total UNION
SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 2), 0) AS total UNION
SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 3), 0) AS total";
$stats_query = mysqli_query ($db_connection, $query);
$result = "";
while ($row = mysqli_fetch_assoc($stats_query)) {
$result .= $row['total'].",";
}
echo ($result);
// OUTPUT: 0,176,68,
As you can see, I'm telling mysql to return me a "0" in case there are no rows for that month (which is the case for January).
There are a total of 12 SELECTS in that query (I copied just 3 to save space), one for each month. Some months will return a value, others won't (which the IFNULL should then convert to a "0").
My final output, for all the 12 months, should look like this:
// OUTPUT: 0,176,68,0,0,0,0,0,12,15,176,43,
BUT... if there is more than one SELECT that returns no rows, the query won't add another "0" to the result. My final result ends up being like this:
// OUTPUT: 0,176,68,12,15,176,43,
It's like the IFNULL is only executed once, even though he's present in all the 12 SELECTS...
Am I doing something wrong? Can anyone spot an error in my code or something?
Thank you!
Use UNION ALL instead of UNION to get all results:
SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 1), 0) AS total UNION ALL
SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 2), 0) AS total UNION ALL
SELECT IFNULL((SELECT SUM(score) FROM statistics WHERE MONTH(date) = 3), 0) AS total
UNION returns only DISTINCT rows.
From doc:
The default behavior for UNION is that duplicate rows are removed from
the result.

MySQL group by value and max date

I need to extract the last character of columns result_1 and result_2 and group them so I have a list from 0 to 9 indicating when it was generated.
In the folowing code I managed to obtain a list from 0 to 9 but the date is the earliest date in the table and not the latest.
$sql = "SELECT * FROM ((SELECT RIGHT(result_1, 1) AS results, date
FROM act_results ORDER BY date ASC)
UNION ALL (SELECT RIGHT(result_2, 1) AS results, date
FROM act_results)) s WHERE results != ''";
$sql .= " GROUP BY results";
$table = mysql_query($sql);
while ($row = mysql_fetch_array($table)) {
echo $row['results']." (".$row['date'].") <br>";
}
Any ideas how to fix it?
Thanks in advance.
Use group by with max():
SELECT results, max(date)
FROM ((SELECT RIGHT(result_1, 1) AS results, date
FROM act_results
) UNION ALL
(SELECT RIGHT(result_2, 1) AS results, date
FROM act_results
)
) s
WHERE results <> ''
GROUP BY results;

Combining two MYSQL Queries into a single one

I am trying to combine two MYSQL Queries into one. What I want to do is select the first and last row added for each day and subtract the last column for that day from the first column of that day and output that. What this would do is give me a net gain of XP in this game for that day.
Below are my two queries, their only difference is ordering the date by DESC vs ASC. the column in the database that i want to subtract from each other is "xp"
$query = mysql_query("
SELECT * FROM (SELECT * FROM skills WHERE
userID='$checkID' AND
skill = '$skill' AND
date >= ".$date."
ORDER BY date DESC) as temp
GROUP BY from_unixtime(date, '%Y%m%d')
");
$query2 = mysql_query("
SELECT * FROM (SELECT * FROM skills WHERE
userID='$checkID' AND
skill = '$skill' AND
date >= ".$date."
ORDER BY date DESC) as temp
GROUP BY from_unixtime(date, '%Y%m%d')
");
SELECT FROM_UNIXTIME(date, '%Y%m%d') AS YYYYMMDD, MAX(xp)-MIN(xp) AS xp_gain
FROM skills
WHERE userID = '$checkID'
AND skill = '$skill'
AND date >= $date
GROUP BY YYYYMMDD
This assumes that XP always increases, so it doesn't need to use the times to find the beginning and ending values.
If that's not a correct assumption, what you want is something like this:
SELECT first.YYYYMMDD, last.xp - first.xp
FROM (subquery1) AS first
JOIN (subquery2) AS last
ON first.YYYYMMDD = last.YYYYMMDD
Replace subquery1 with a query that returns the first row of each day, and subquery2 with a query that returns the last row of each day. The queries you posted in your question don't do this, but there are many SO questions you can find that explain how to get the highest or lowest row per group.

How do I create an array of data for 30 days from database table where some dates are not entered?

Let's say you have a simple table with:
ID IP CREATED_DATE
-------------------------------------------------------
1 111.111.111.111 2011-03-28 14:12:31
2 111.111.111.111 2011-03-29 03:38:12
3 222.222.222.222 2011-04-02 12:04:45
4 111.111.111.111 2011-04-02 22:13:23
5 333.333.333.333 2011-04-03 05:53:15
6 222.222.222.222 2011-04-05 02:13:51
7 111.111.111.111 2011-04-07 11:45:34
I need to query the last 30 days and get a count of unique ips and total rows per day even if there are no entries for that day. So days that are not entered would obviously just be 0 as the array value for both unique and total rows.
If you have an integers table, you can generate all the days in your desired timespan and join those with the tallies of IPs for each day appearing in your table:
SELECT timespan."day",
COALESCE(num_uniq_ips, 0) AS num_uniq_ips,
COALESCE(num_records, 0) AS num_records
FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL i DAY) AS "day"
FROM integers
WHERE i < 30) timespan
LEFT JOIN (SELECT DATE(created_date) AS "day",
COUNT(DISTINCT ip) AS num_uniq_ips,
COUNT(1) AS num_records
FROM so6025149
GROUP BY 1) tallies
ON timespan."day" = tallies."day"
ORDER BY timespan."day" ASC;
You can create a temporary table, populate it with the past 30 days and use that in your query. From PHP code:
// create table with past 30 days
$buffer = "CREATE TEMPORARY TABLE IF NOT EXIST past_month (val DATETIME NOT NULL );";
$now = new DateTime(now);
for($i=30;$i>0;$i++)
{
$buffer += "INSERT INTO past_month VALUES(" . $now . ");";
$now->sub(new DateInterval('P1D'));
}
mysql_query($buffer);
// the query
$sql= "SELECT
val,
(SELECT COUNT(IP)
FROM table
WHERE DATE_FORMAT(CREATED_DATE,'%Y-%m-%d) = DATE_FORMAT(val,'%Y-%m-%d') As UNIQUE_IPS
FROM
past_month";
$result = mysql_query($sql);
SELECT COUNT(DISTINCT column_name)
FROM table_name
WHERE ( DateTime > (GetDate()-30) )
something along those lines

Categories