php mysql sort by number of rows descending - php

can you help me
$sql="select * from table1 where id='1,2,3,4'";
{
$sql2="select distinct column1 from table2 where column2='".$row['id']."' and left(date,10) BETWEEN '".$date_from."' AND '".$date_to."'";
}
I need to sort $sql by number of rows descending for $sql2 by id

If I understand you correctly, you want the results from $sql ordered by number of rows found by $sql2 for each row in $sql. This join should do that, it joins table2 and orders by the count, descending.
SELECT t1.id
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id=t2.column2
WHERE id IN (1,2,3,4) -- should it really be = '1,2,3,4'?
AND LEFT(date,10) BETWEEN '2013-01-01' AND '2013-12-31'
GROUP BY t1.id
ORDER BY COUNT(DISTINCT t2.column1) DESC
An SQLfiddle to test with.

Related

Mysql Query search by latest date with group by

This is my table structure
and this is my dataset
What I want is query that gets data ordered by date desc and group by id_patient
so the result in the dataset example should be like this:
I would go with limit clause with subquery since you have PK :
select *
from table t
where id = (select t1.id
from table t1
where t1.id_patient = t.id_patient
order by t1.date desc
limit 1
);
However, if single patient has multiple same dates then this would produce only single records based on date.
SELECT * from rdv a JOIN (SELECT id_patient,MAX(date) date FROM rdv GROUP by id_patient ) b on a.id_patient = b.id_patient and a.date = b.date
If you want the latest record for each patient, then you are not looking for an aggregation. I would often approach this with a correlated subquery:
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.id_patient = t.id_patient);
SELECT *
FROM table
GROUP BY group by id_patient
ordered by DATE(date) desc;

Count the number of rows with the same id [PHP]

So I want to count and echo the number of rows from table2, which have the same id row as table1.
I understand the function mysqli_num_rows funtion, but how can I make it count the rows from table2 that have the matching id?
Total newbie, and still searching. Thought this might help me get in the right direction. Thanks for any help !
mysqli_num_rows return the number of rows from a result.
You should write an other query to return the number of rows in table 2 with the same id
SELECT COUNT(*)
FROM table2
WHERE table2.id = <id>
CREATE TABLE table1 (id INT);
CREATE TABLE table2 (id INT);
INSERT INTO table1 VALUES (1), (2), (3), (4);
INSERT INTO table2 VALUES (2), (4);
SELECT COUNT(*)
FROM table1
JOIN table2
ON table1.id = table2.id;
Try it here: http://sqlfiddle.com/#!9/0d289/1
To only count
select count(*)
from table1, table2
where table1.id = table2.id
To know what id and how much
select table2.id, count(*)
from table1, table2
where table1.id = table2.id
group by table2.id
The second case on sqlfiddle.com
Try this:
SELECT `table2`.`id`, COUNT(`table2`.`id`) AS `num_rows`
FROM `table2`
LEFT JOIN `table1` ON `table2`.`id` = `table1`.`id`
WHERE `table2`.`id` IS NOT NULL
GROUP BY `table2`.`id`
ORDER BY `table2`.`id` ASC

PHP / MYSQL Statement so select Max Sum of Join

I have Problems with a select statement, as a little help here are the important columns:
Table1
ID NAME
TABLE 2
ID U_ID COUNTER
The ID of Table 1 Matches the U_ID of Table 2. Table 2 contains many entries for the same u_id.
What I want to do is to get the Name of the "user" (table 1) who has in sum the max. counter.
What I got since now is the join of the tables (Where clause depends on other rows which are not important for the problem).
Can anyone help me on this issue?
So what you need is an aggregate of an aggregate (max of sum of column). The easiest will be to create a view providing the sum and u_id end then select the max of it:
create view table2sums
as
select u_id, sum(counter) as total
from table2
group by u_id;
and then
select t1.name
from table1 t1, table2sums t2
where t1.id = t2.u_id
and t2.total >= all (
select total
from table2sums
)
In this special case you can also do it directly:
select t1.name
from table1 t1, table2 t2
where t1.id = t2.u_id
group by t1.name
having sum(t2.counter) >= all (
select sum(counter)
from table2
group by t2.u_id
)
NOTE: The other proposed solutions will show a better performance. My solution only selects the name (which is what you said you wanted) and works in any RDBMS.
There exist RDBMS without the LIMIT possibility.
In the end, I'd say: regard my solution as educational, the others as practical
SELECT name,
SUM(counter) as counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY counter DESC
LIMIT 1
You can try this:
SELECT name, SUM(counter) as total_counter
FROM table1
JOIN table2
ON table1.id = table2.u_id
GROUP BY u_id
ORDER BY total_counter DESC
LIMIT 1
Working Demo: http://sqlfiddle.com/#!2/45419/4

PHP SQL JOIN Avoid ID Duplicates

I am using this code:
SELECT * FROM Table1
JOIN Table2 USING(venue_id)
WHERE table2.location = '$MyVariable'
Then to count the number of records return:
$num_rows = mysql_num_rows($result);
echo "$num_rows";
It works great but venue_id in Table1 has lots of entries and I only want it to get one per venue_id
How can I make it so it only returns 1 venue_id instance?
Use GROUP BY clause,
SELECT * FROM Table1
JOIN Table2 USING(venue_id)
WHERE table2.location = '$MyVariable'
GROUP BY `Table1`.`venue_id`

php multiple mysql commands in array

Is it possible build an array of SQL commands to query the DB? What I have is three tables, each have columns with amounts due. Would like to select anything that is due and display on screen so it can be invoiced (preferably in a table) and each row with it's respective customers dues.
I can select everything that is due using UNION ALL between the three tables, however I cant figure out how to list them by ID in the table row.
Below is what I have so far. At this pace I'll have to run each query separately and list them in three separate lists. Suggestions?
<table>
<tr>
<th> ID</th>
<th> Cost 1</th>
<th> Cost 2</th>
<th> Cost 3</th>
</tr>
<?php
$list1 = "SELECT ID, Cost FROM Table1 WHERE Invoiced IS NULL;";
//$list2 = "SELECT ID, Price2 FROM Table2 WHERE Expiration BETWEEN '$curDate' AND '$maxDate';";
//$list3 = "SELECT ID, Price3 FROM Table3 WHERE Expiration BETWEEN '$curDate' AND '$maxDate'";
$result = mysql_query($list1, $link) or die(mysql_error());
$num_rows = mysql_num_rows($result);
$num_fields = mysql_num_fields($result);
for ($i=0; $i<$num_rows; $i++) {
for ($j=0; $j<$num_fields; $j++) {
$invoice[$i][mysql_fieldname($result,$j)] = mysql_result($result,$i,mysql_field_name($result,$j));
}
}
//eventually the order it should be listed on screen
for($i=0; $i<count($invoice); $i++) {
echo "<tr><td>".$invoice[$i]["ID"]."</td>
<td>".$invoice[$i]["Cost"]."</td>
<td>".$invoice[$i]["Price2"]."</td>
<td>".$invoice[$i]["Price3"]."</td></tr>";
}
?>
</table>
Edit after comment:
Query being passed and returning syntax error You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'all LEFT JOIN table1 ON all.ID = table1.ID LEFT JOIN t' at line 7:
$query = "
SELECT all.ID, table1.Cost1, table2.Price2, tabl3.Price3
FROM
(SELECT ID, Cost1 FROM table1 WHERE Invoiced IS NULL
UNION
SELECT ID, Price2 FROM table2 WHERE Expiration BETWEEN '$curDate' AND '$maxDate'
UNION
SELECT ID, Price3 FROM table3 WHERE Expiration BETWEEN '$curDate' AND '$maxDate') AS all
LEFT JOIN table1 ON all.ID = table1.ID
LEFT JOIN table2 ON all.ID = table2.ID
LEFT JOIN table3 ON all.ID = table3.ID
";
From the table header you have created above which places the three Cost columns in a single row by ID, you seem to imply that you want to to JOIN the three tables together on their ID. I am using a LEFT JOIN here, to be sure that all rows from Table1 are present, even if there is no corresponding row in either of the other two tables.
SELECT
Table1.ID,
Table1.Cost as Cost1,
Table2.Price2 AS Cost2,
Table3.Price3 AS Cost3
FROM
Table1
LEFT JOIN Table2 ON Table1.ID = Table2.ID
LEFT JOIN Table3 ON Table1.ID = Table3.ID
WHERE
Table1.Invoiced IS NULL
AND Table2.Expiration BETWEEN '$curDate' AND '$maxDate'
AND Table3.Expiration BETWEEN '$curDate' AND '$maxDate'
Update after comments:
In the case that Table2 may have an ID not held in Table1 or Table3, for example (where Table1.ID can't be considered authoritative), you can get the total set of DISTINCT ID from all 3 tables via a UNION and use that to join against:
SELECT
allID.ID,
Table1.Cost1,
Table2.Price2 AS Cost2,
Table2.Price3 AS Cost3
FROM
/* Subquery gets a distinct set of IDs from all tables via UNION
so the outer query has a complete list to join against the other tables */
(
SELECT ID FROM Table1
UNION SELECT ID FROM Table2
UNION SELECT ID FROM Table3
) allID
LEFT JOIN Table1 ON allID.ID = Table1.ID
LEFT JOIN Table2 ON allID.ID = Table2.ID
LEFT JOIN Table3 ON allID.ID = Table3.ID
/* Sorry, forgot the WHERE clause here */
WHERE
Table1.Invoiced IS NULL
AND Table2.Expiration BETWEEN '$curDate' AND '$maxDate'
AND Table3.Expiration BETWEEN '$curDate' AND '$maxDate'
Note that the existence of three tables with nearly identical column structures in a one-to-one relationship probably implies a design problem. You might consider combining these into a single table.
A further note about the PHP:
In PHP, we almost never use an incremental for loop for iteration as you would in C/C++. Instead, we typically make use of a foreach or when fetching rows from a query, a while loop.
// Fetch in a while loop
$invoice = array();
// $result is your query resource as you already have it...
while ($row = mysql_fetch_assoc($result)) {
// Accumulate rows into $invoice array
$invoice[] = $row;
}
// Then loop over the array:
foreach ($invoice as $inv) {
echo "<tr>
<td>{$inv['ID']}</td>
<td>{$inv['Cost1']}</td>
<td>{$inv['Cost2']}</td>
<td>{$inv['Cost3']}</td>
</tr>";
}
Final update:
Yes, the WHERE clause will restrict for all conditions met. If you need to limit them individually, you must do so in subqueries which are then joined together, using the same UNION subquery to get the distinct set of ID
SELECT
allID.ID,
T1.Cost1,
T2.Price2 AS Cost2,
T3.Price3 AS Cost3
FROM
(
SELECT ID FROM Table1
UNION SELECT ID FROM Table2
UNION SELECT ID FROM Table3
) allID
LEFT JOIN (SELECT ID, Cost AS Cost1 FROM Table1 WHERE Invoiced IS NULL) T1 ON allID.ID = T1.ID
LEFT JOIN (SELECT ID, Price2 AS Cost2 FROM Table2 WHERE Expiration BETWEEN '$curDate' AND '$maxDate') T2 ON allID.ID = T2.ID
LEFT JOIN (SELECT ID, Price3 AS Cost3 FROM Table3 WHERE Expiration BETWEEN '$curDate' AND '$maxDate') T3 ON allID.ID = T3.ID

Categories