Add COUNT and DISTINCT in $query - php

How to add select COUNT and DISTINCT in the below $query? Please let me know if you need any other details to solve this issue. Thank you for your time.
if(isset($_POST["intake_year"]))
{
$query = "
SELECT * FROM marketing_data
WHERE intake_year = '".$_POST["intake_year"]."'
";
$statement = $connect->prepare($query);
$statement->execute();
$result = $statement->fetchAll();
foreach($result as $row)
{
$output[] = array(
'semester' => $row["semester"],
'student_matric' => floatval($row["count"])
);
}
echo json_encode($output);
}
//SELECT count(student_matric) AS count, semester, intake_year FROM marketing_data GROUP BY intake_year - This query is to only COUNT student_matric
//SELECT DISTINCT semester FROM marketing_data ORDER BY semester DESC - This query is to only DISTINCT semester

I guess you are looking for something like that
$query = "
SELECT distinct semester , count(student_matric) as count FROM marketing_data
WHERE intake_year = '".$_POST["intake_year"]."'
Group by student_matric " ;

Related

How to shuffle posts in two tables?

I was working on a post system..
So, I have to show posts by friends of the user and the groups in which user has participated..
Here is my code to show posts..
<?php
$sql = "SELECT * FROM posts WHERE uploader_id=:friend_id ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":friend_id" => $friend_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
$sql = "SELECT * FROM group_posts WHERE id=:member_group ORDER BY id DESC";
$query = $db->prepare($sql);
$query->execute(array(
":member_group" => $group_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$name = $row['name'];
echo "POST BY $name";
}
?>
Now, I want all these posts to be shuffled in a way that all the posts of the post table and group_posts table are shown in the descending order.
UPDATE
I edited my code to this..
I figured out that first I'll have to code this before coding my post system..
<?php
$sql = "SELECT * FROM friends WHERE user_one=:me OR user_two=:me2 UNION SELECT * FROM group_members WHERE member_id=:me3";
$query = $db->prepare($sql);
$query->execute(array(
":me" => $my_id,
":me2" => $my_id,
":me3" => $my_id
));
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
$user_one = $row['user_one'];
$user_two = $row['user_two'];
$group_id = $row['group_id'];
if ($user_one == $my_id) {
$friend_id = $user_two;
} else {
$friend_id = $user_one;
}
echo $friend_id . "<BR>" . $group_id;
}
?>
Now, here's the problem..
This is successfully printing the $friend_id but, it shows an undefined index 'group_id' while printing $group_id.
I have checked all the fields are correct.
Try using just one query with UNION
SELECT *
FROM (
SELECT name, id FROM posts WHERE uploader_id=:friend_id
UNION
SELECT name, id FROM group_posts WHERE id=:member_group
) p
ORDER BY p.id DESC
Note, your inner queries must return the same number of columns in the same order (and I think with the same name/alias, too).

SQL Select count of repeated dates

I'm trying to select count of repeated dates and output its numbers
$user_curr_id = $_SESSION['user_id'];
$sql = "SELECT COUNT(datum) FROM table_name WHERE user_ids = $user_curr_id";
I have no idea how to do it.
2014-07-23,2014-07-23,2014-07-23 => 3
2014-07-24,2014-07-24 =>2
2014-07-25 => 1
and get $result = 3,2,1
I assume you're looking after the GROUP BY clause:
$sql = "SELECT datum, COUNT(datum) as cnt
FROM table_name
WHERE user_ids = $user_curr_id
GROUP BY datum
ORDER BY COUNT(datum) DESC;";
if your column datum is of the data type DATE.
Note
As already mentioned you're vulnerable to sql injection. You should use a parameterized prepared statement and bind your input value to this parameter like that:
$sql = "SELECT datum, COUNT(datum) cnt
FROM table_name
WHERE user_ids = ?
GROUP BY datum
ORDER BY COUNT(datum) DESC;";
$result = array();
if ($stmt = $mysqli->prepare($sql)) {
if ($stmt->bind_param('s', $user_curr_id)) {
if($res = $stmt->execute()) {
while ($row = $res->fetch_assoc()) {
$result[] = $row['cnt']; // add the content of field cnt
}
}
}
}
echo implode(',', $result);

mySQL Order by Most Commented and Least Commented

I'm trying to order a list of items based on the amount of comments for each topic as shown below:
$page = $_GET['page'];
$query = mysql_query("SELECT * FROM topic WHERE cat_id='$page' LIMIT $start, $per_page");
if (mysql_num_rows($query)>=1)
{
while($rows = mysql_fetch_array($query))
{
$number = $rows['topic_id'];
$title = $rows['topic_title'];
$description = $rows['topic_description'];
//get topic total
$sqlcomment = mysql_query("SELECT * FROM comments WHERE topic_id='$number'");
$commentnumber = mysql_num_rows($sqlcomment);
// TRYING TO ORDER OUTPUT ECHO BY TOPIC TOTAL ASC OR DESC
echo "
<ul>
<li><h4>$number. $title</h4>
<p>$description</p>
<p>$topictime</p>
<p>$commentnumber</p>
</li>
</ul>
";
}
}
else
{
echo "<p>no records available.</p><br>";
}
What would be the best way to order each echo by $num_rows (ASC/DESC values)? NOTE: I've updated with the full code - I am trying to order the output by $commentnumber
The first query should be:
SELECT t.*, COUNT(c.topic_id) AS count
FROM topic AS t
LEFT JOIN comments AS c ON c.topic_id = t.topic_id
WHERE t.cat_id = '$page'
GROUP BY t.topic_id
ORDER BY count
LIMIT $start, $per_page
You can get $commentnumber with:
$commentnumber = $rows['count'];
You don't need the second query at all.
First of all you have error here
echo "divs in order from least to greatest "number = $num_rows"";
It should be
echo "divs in order from least to greatest number = " . $num_rows . "";
And about the most commented try with
$sql = "SELECT * FROM `table` WHERE `id` = '$id' ORDER BY column DESC/ASC";
Or if there is not count column try with
$sql = "SELECT * FROM `table` WHERE `id` = '$id' ORDER BY COUNT(column) DESC/ASC";

Query to get top 5 users by total month sales amount

I was hoping you could help me figure this out. I would like to run a query that would search a table and all it's rows and the date matches the current month. Then return the user_id. What I am trying to achieve is gathering the top 5 user id's under this query.
How can I change this to find the top 5 for the current month? I am usually able to figure out my queries but this one has me stumped.
This is all I have at the moment.
$top = mysqli_query($mysqli, "SELECT sum(amount) AS total FROM sales WHERE status = 'S' AND MONTH(date) = 1");
while($row = mysqli_fetch_row($top))
{
$userid = $row['0'];
}
Update:
$top = mysqli_query($mysqli, "SELECT user_id
FROM
(
SELECT user_id, SUM(amount) total
FROM sales
WHERE status = 'S'
AND MONTH(date) = MONTH(CURDATE())
AND YEAR(date) = YEAR(CURDATE())
GROUP BY user_id
) q
ORDER BY total DESC
LIMIT 5");
while($row = mysqli_fetch_row($top))
{
$topsales[] = $row['0'];
}
foreach($topsales as $topsale) {
echo $topsale;
}
Are you looking for a query like this?
SELECT user_id
FROM
(
SELECT user_id, SUM(amount) total
FROM sales
WHERE status = 'S'
AND MONTH(date) = MONTH(CURDATE())
AND YEAR(date) = YEAR(CURDATE())
GROUP BY user_id
) q
ORDER BY total DESC
LIMIT 5
or just
SELECT user_id
FROM sales
WHERE status = 'S'
AND MONTH(date) = MONTH(CURDATE())
AND YEAR(date) = YEAR(CURDATE())
GROUP BY user_id
ORDER BY SUM(amount) DESC
LIMIT 5
Here is SLQFiddle demo
Note: using MONTH() and YEAR() functions will prevent MySql from using any index you might have on date column
Now your php code might look like this
$db = new mysqli('localhost', 'user', 'password', 'dbname');
if ($db->connect_errno) {
die('Cannot connect'); // TODO: better error handling
}
$sql = "SELECT user_id
FROM sales
WHERE status = 'S'
AND MONTH(date) = MONTH(CURDATE())
AND YEAR(date) = YEAR(CURDATE())
GROUP BY user_id
ORDER BY SUM(amount) DESC
LIMIT 5";
$topsales = array();
if ($query = $db->prepare($sql)) {
$query->execute();
$query->bind_result($user_id);
while ($query->fetch()) {
$topsales[] = $user_id;
}
$query->close();
} else {
die('Unable to prepare: ' . $db->error); // TODO: better error handling
}
$db->close();
foreach ($topsales as $topsale) {
echo $topsale . '<br>';
}

data from few MySQL tables sorted by ASC

In the dbase I 've few tables named as aaa_9xxx, aaa_9yyy, aaa_9zzz. I want to find all data with a specified DATE and show it with the TIME ASC.
First, I must find a tables in the dbase:
$STH_1a = $DBH->query("SELECT table_name
FROM information_schema.tables
WHERE table_name
LIKE 'aaa\_9%'
");
foreach($STH_1a as $row)
{
$table_name_s1[] = $row['table_name'];
}
Second, I must find a data wit a concrete date and show it with TIME ASC:
foreach($table_name_s1 as $table_name_1)
{
$STH_1a2 = $DBH->query("SELECT *
FROM `$table_name_1`
WHERE
date = '2011-11-11'
ORDER BY time ASC
");
while ($row = $STH_1a2->fetch(PDO::FETCH_ASSOC)) {
echo " ".$table_name_1."-".$row['time']."-".$row['ei_name']." <br>";
}
}
.. but it shows the data sorted by tables name, then by TIME ASC. I must to have all this data (from all tables) sorted by TIME ASC.
Thank You dev-null-dweller, Andrew Stubbs and Jaison Erick for your help.
I test the Erick solution :
foreach($STH_1a as $row) {
$stmts[] = sprintf('SELECT *
FROM %s
WHERE date="%s"', $row['table_name'], '2011-11-11');
}
$stmt = implode("\nUNION\n", $stmts);
$stmt .= "\nORDER BY time ASC";
$STH_1a2 = $DBH->query($stmt);
while ($row_1a2 = $STH_1a2->fetch(PDO::FETCH_ASSOC)) {
echo " ".$row['table_name']."-".$row_1a2['time']."-".$row_1a2['ei_name']." <br>";
}
it's working but I've problem with 'table_name' - it's always the LAST table name.
//----------------------------------------------------------------------
...and the ending solution with all fixes, thanks all for your help, :))
foreach($STH_1a as $row) {
$stmts[] = sprintf("SELECT *, '%s' AS table_name
FROM %s
WHERE date='%s'", $row['table_name'], $row['table_name'], '2011-11- 11');
}
$stmt = implode("\nUNION\n", $stmts);
$stmt .= "\nORDER BY time ASC";
$STH_1a2 = $DBH->query($stmt);
while ($row_1a2 = $STH_1a2->fetch(PDO::FETCH_ASSOC)) {
echo " ".$row_1a2['table_name']."-".$row_1a2['time']."-".$row_1a2['ei_name']." <br>";
}
Instead of printing the line as you fetch it from db, gather all data in one array taht you will be able to sort with usort and your own callback function.
Other option is to get it sorted directly from mysql, using UNION selects like this:
$SQL = "
(SELECT '$table_name_1' AS tbl_name, time, ei_name FROM `$table_name_1` WHERE date = '2011-11-11')
UNION
(SELECT '$table_name_2' AS tbl_name, time, ei_name FROM `$table_name_2` WHERE date = '2011-11-11')
UNION
(SELECT '$table_name_3' AS tbl_name, time, ei_name FROM `$table_name_3` WHERE date = '2011-11-11')
ORDER BY time ASC
";
You need to use the UNION sql directive:
<?php
$STH_1a = $DBH->query("SELECT table_name
FROM information_schema.tables
WHERE table_name
LIKE 'aaa\_9%'");
$stmts = array();
foreach($STH_1a as $row)
{
$stmts[] = sprintf('SELECT *, %s AS `table_name` FROM %s WHERE date="%s"', $row['table_name'], $row['table_name'], '2011-01-01');
}
$stmt = implode("\nUNION\n", $stmts);
$stmt .= "\nORDER BY time ASC";
$STH_1a2 = $DBH->query($stmt);
FIX: Included the table name as returned value.
The correct way to fix it will be to UNION your selection data as stated in other answers.
A quick fix would be to change your second code block to something like:
$Sorted = array();
foreach($table_name_s1 as $table_name_1)
{
$STH_1a2 = $DBH->query("SELECT *
FROM `$table_name_1`
WHERE date = '2011-11-11'
ORDER BY time ASC
");
while ($row = $STH_1a2->fetch(PDO::FETCH_ASSOC)) {
$Sorted[$row['time']] = " ".$table_name_1."-".$row['time']."-".$row['ei_name']." <br>";
}
}
ksort($Sorted);
foreach($Sorted as $Entry) {
echo $Entry;
}
Note: This will 'fail' for cases where there are multiple entries for one date.

Categories