count(*) in each of previous 25 months separately - php

I have a database name "d" and there is table name "t"...
t has two columns id and month...
I have to calculate no of ids in each month.
actually, I am taking an input in $monthyear, now I want to store count(id) of previous 25 month in a $row
I use this type of commands
$search = "SELECT * FROM `d`.`t` where id>2";
$result = mysqli_query($con, $search);
$row = mysqli_fetch_array($result);
please tell me a query which can do this trick and can you store it like
$row[0]="no of ids in the inputed month"
$row[1]="no of ids in the [inputed month - 1 month]"
$row[2]="no of ids in the [inputed month - 2 month]"
and so on....
note: both month and "years" do matter.

If not all month has IDs , then you need to use a derived table. Something like this:
SELECT t.monthyear, COALESCE(COUNT(s.monthyear),0) as numOfID
FROM(SELECT '012016' as monthyear
UNION ALL
SELECT '022016'
....) t
LEFT JOIN YourTable s
ON(t.monthyear = s.monthyear)
GROUP BY t.monthyear

Related

Find record older / newer than the current record in SQL

I am trying to write a SQL statement that gives me a previous / next record.
My posts table has records that are either a blog post or a ships log (based on the column posts_isLog being either a 1 or 0).
I am using the following prepared statement to return the current ships log based on the date. The column post_createdOn is a date/time data type. I am using a like statement to match my passed date to the query as this is found via the URL so "shipslog/14th-April-2020". The date is changed to match the data so yyyy-mm-dd so no issues there.
//query
$this->db->query('SELECT *
from posts
INNER JOIN voyages ON posts.post_voyage = voyages.voyage_id
WHERE post_createdOn LIKE :date
AND post_isLog = 1
AND post_live = 1');
//bind values
$this->db->bind(':date', '%'.$date.'%');
//get the results
$row = $this->db->single();
return $row;
I can't work out the SQL to use find the next / previous ships log based on the current record.
I think what I am looking to write is something like... "Select all from posts where post_createdOn is less than the current record's post_createdOn date".
I am trying
//query
$this->db->query('SELECT *
from posts
WHERE post_createdOn < :date
AND post_isLog = 1
AND post_live = 1');
//bind values
$this->db->bind(':date', '%'.$date.'%');
//get the results
$row = $this->db->single();
return $row;
But I know this isn't referring to the current record. Completely stumped!
This is the refering $this->db->single();
//get single record as an object
public function single() {
$this->execute();
return $this->statement->fetch(PDO::FETCH_OBJ);
}
Thanks to all the answers!
It seems I was nearly there after #RiggsFolly's help. I took out the % and the query returned a result. I needed to order the results as I was only returning the first row!
public function getPreviousLog($date) {
//query
$this->db->query('SELECT *
from posts
WHERE post_createdOn < :date
AND post_isLog = 1
AND post_live = 1
ORDER BY post_createdOn DESC');
//bind values
$this->db->bind(':date', $date);
//get the results
$row = $this->db->single();
}
You could use LAG and LEAD for this but it's a bit tedious if you have a lot of columns. Instead try:
WITH cte AS(
SELECT *, ROW_NUMBER() OVER(ORDER BY post_CreatedOn) rn
FROM posts
WHERE
post_createdOn < :date AND
post_isLog = 1 AND
post_live = 1
)
SELECT *
FROM
cte curr
LEFT JOIN cte next ON curr.rn+1 = next.rn
LEFT JOIN cte prev ON curr.rn-1 = prev.rn
You don't seem to specify any partition - you just say that your table is one long stream of dated records and each record has a prev and a next according to the date. If there is some sort of notion that groups of columns belong together, put the thing that groups them into the row number as a PARTITION BY and also add it to the join ON clauses between prev curr and next
I'm not entirely clear on whether you want the "next" row if it it outside the date limit. Eg if you have two rows 2000-12-31 and 2001-01-01 and you set your date parameter to 2001-01-01 then the later record will be excluded as "current" but does it mean that the 2000-12-31 row should have a "next" that is null, or is the 2001-01-01 row
If it should (this query will not return it) take the predicate out of the CTE and put it in the main query WHERE, on curr.post_createdOn instead
If you're making some kind of pagination system, with one log per day and you want 3 rows, consider:
WITH cte AS(
SELECT *
FROM posts
WHERE
post_isLog = 1 AND
post_live = 1
)
SELECT. *
FROM cte
WHERE post_createdOn IN(
SELECT MAX(post_createdOn) FROM cte WHERE post_createdOn < #date
UNION ALL
SELECT #date
SELECT MIN(post_createdOn) FROM cte WHERE post_createdOn > #date
)

Sum values in multidimensional array (selecting multiple columns with multiple rows)

Let's say I have 5 different columns, a, b, c, d, e, and I'm selecting multiple rows:
$result = mysqli_query($conn,"SELECT a,b,c,d,e FROM posts WHERE submitter='$user'");
while ($row = mysqli_fetch_assoc($result)){
$ratings[] = $row;
}
Example:
The user has 3 posts, so it'll select 3 rows in the query.
I want to sum all of the rows' values for a (and the rest of course).
e.g.
row 1 a value = 4
row 2 a value = 10
row 3 a value = 1
So I need to sum all of those to get 15.
I know to use array_sum($ratings) to find the sum of the array but only if you select one column (a) which can have multiple rows, but this is multi-dimensional right due to multiple column values being selected?
You can just use sum in your query:
select sum(a)
, sum(b)
, sum(c)
, sum(d)
, sum(e)
from posts
where submitter = '$user'
You can use count aggregate function and group by in MySQL.
SELECT
submitter,
count(a) as rating
FROM posts
WHERE submitter='$user'
GROUP BY submitter
A a result you will get something like that:
some submitter, 3
another submitter, 10
one more submitter, 1
Is this helpful?

Mysql Query wont echo all results! PHP

My code goes like this,
$sql = "SELECT Month(time) as Month, Year(time) as Year,
title, COUNT(*) AS total FROM posts GROUP BY Year, Month ORDER BY time DESC";
$stmt = $conn->query($sql);
if ($stmt->num_rows > 0) {
while($row = $stmt->fetch_array()){
echo "<div class=title>" . $row["title"]. "</div>";
}
}
it is supposed to output 4 titles,
Bellavisa
Mist Neting
Turkey is cool!
Cock of the Rock
but it only outputs
Bellavisa
Turkey is cool!
Cock of the Rock
Note that bellavisa and mist neting are in the same year and month, (setting up an archive list)
EDIT
Here is some of the table data
title "bellavisa" content "yadadada" time "timestamp ..." Author "author"
title "mist nesting" content "yadadada" time "timestamp ..." Author "author"
Well, title is per post, so to get all the titles you should use no GROUP BY, while COUNT(*) is per month, so to get counts you need to GROUP BY the way you do, so in a simple SELECT you can either select one or another, but not both.
To select both, you need to use a subquery, something along the lines of
$sql = "SELECT Month(time) as Month, Year(time) as Year, title, (SELECT COUNT(*) FROM posts WHERE Month(time) = Month AND Year(time) = Year) AS total FROM posts ORDER BY time DESC;";
Effectively, the query selects all the posts, and for each post computes a count. It is not the most efficient way to do that, you can rewrite it using a join, if every post has a unique ID. But for a table with reasonable size this query will work just fine.

count the number of times a value appears in a column where liked_id matches likes?

does anyone know how you would count the total number of times a value appears in a single column.
for instance my table looks like:
user_id | liked_id | likes
3 1 1
4 1 1
what i want to do is count the total of the likes column where liked_id matches.
So liked_id 1 has 2 likes?
can someone please show me how i might do this?
function count_likes() {
global $connection;
global $profile_id;
$query = "SELECT likes, count(*) FROM ptb_likes GROUP BY liked_id";
$count_likes_set = mysql_query($query, $connection);
confirm_query($count_likes_set);
return $count_likes_set;
}
Try this:
SELECT liked_id, SUM(likes) FROM ptb_likes GROUP BY liked_id
you should grouped them by liked_id
SELECT liked_id, count(*) totalLikes
FROM ptb_likes
GROUP BY liked_id
if you just want the number of rows with like_id of 1,
SELECT liked_id, COUNT(likes) FROM ptb_likes WHERE liked_id = 1;
If you want the the frequency of each like_id:
SELECT liked_id, COUNT(likes) FROM ptb_likes GROUP BY liked_id;
As a note: don't use SUM as that adds all the values of like_id, and if you have a like_id greater than 1, your count will be wrong. Use count instead.

mysql collection of visitor days?

I have a mysql table - table1. It has ID (autoinc), dt (datetime), name (varchar) columns. When a visitor visits they can enter their name in the database. On some days their are no visitors.
From this, i'm trying to find if their is some way to make a list in php of all days for which their was at least 1 visitor.
Any ideas?
Select distinct date(dt) from table1
So then, in php you would do something like:
$result = mysql_query("select distinct date(dt) from table1");
while($row = mysql_fetch_array($result)){
echo $row[0] . "\n";
}
This would print each date on a different line.
Should give you a list of the unique dates that data was written to the table.
Updated to use date() instead of day()
*Updated to fix the missing parenthesis *
To extract only those dates.
SELECT DATE_FORMAT(dt, '%Y-%m-%d') AS the_date,
COUNT(*) AS visitors
FROM table
GROUP BY the_date
HAVING visitors > 0;

Categories