SQL COUNT Rows from another table - mysql

am trying to count number of rows associated with a particular row from another table
SELECT *
FROM
(
(SELECT COUNT(*) totalusers
FROM mox_admin
, caspartition
WHERE mox_admin.partitionid = caspartition.id
)
) tita
, caspartition
ORDER
BY caspartition.id DESC
LIMIT 0,5
But the query keep returning the total count of rows in the "moz_admin" table
Here is what i did though i think is not the most efficient method
"SELECT * FROM caspartition ORDER BY caspartition.id DESC LIMIT 0, 5";
//execute the query then loop through
while($partition_data = mysqli_fetch_array($result)) {
$partition_id = $partition_data['id'];
$subquery_sql = "SELECT COUNT(*) AS totalusers FROM moz_admin WHERE partitionid = '$partition_id'";
$subquery_sql = mysqli_fetch_array(mysqli_query($conn, $subquery_sql));
$no_of_users = $subquery_sql[totalusers];
}
The whole point is making this a single SQL query instead querying the table for each row i loop through.
Thanks in advance.

You should combine these into one single query. The query would be:
SELECT cp.id, COUNT(a.partitionid) as cnt
FROM (SELECT *
FROM caspartition
ORDER BY caspartition.id DESC
LIMIT 0, 5
) cp LEFT JOIN
moz_admin a
ON a.partitionid = cp.id
GROUP BY cp.id;

Related

Extracting Data Using SQL

How can I display the records received from this query in ASC?
SELECT accounts.Nickname, chat.AccountID, chat.Message, chat.DateTime, accounts.Color
FROM (chat INNER JOIN accounts ON chat.AccountID = accounts.AccountID)
ORDER BY chat.MessageID DESC
LIMIT 100
Put your original query in a derived table (the subquery), and order its result in ASC order.
SELECT * FROM
(
SELECT accounts.Nickname, chat.AccountID, chat.Message, chat.DateTime, accounts.Color, chat.MessageID
FROM (chat INNER JOIN accounts ON chat.AccountID = accounts.AccountID)
ORDER BY chat.MessageID DESC
LIMIT 100
) dt
ORDER BY MessageID ASC

Getting Newest Record from a table using mysql

This has to be a no brainer, but I am stumped. I'm used to using aggregate 'FIRST' in MsAccess, but MySql has no such thing.
Here is a simple table. I want to return the most recent record based on the date,
for each unique 'group ID'. I need the three records in yellow.
I was asked to add my full query. I tried one of the suggestions using the JOIN feature replacing 't' with the temp table name, but it failed to work. "Can't reopen table 't'"
The code is below. I know it's ugly, but it does return the correct data set.
I cleaned up the code a bit and added the JOIN code. Error: "Can't reopen table 't'"
enter code here
DROP TABLE IF EXISTS `tmpMaxLookupResults`;
create temporary table tmpMaxLookupResults
as
SELECT
REPORTS.dtmReportCompleted,
RESULTS.lngMainReport_ID, RESULTS.lngLocationGroupSub_ID
FROM
(tbl_010_040_ProcedureVsTest_Sub as ProcVsSub
INNER JOIN tbl_010_050_CheckLog_RESULTS as RESULTS
ON (ProcVsSub.lngLocationGroupSub_ID = RESULTS.lngLocationGroupSub_ID)
AND (ProcVsSub.lngProcedure_ID = RESULTS.lngProcedure_ID)
AND (ProcVsSub.lngItemizedTestList_ID = RESULTS.lngItemizedTestList_ID)
AND (ProcVsSub.strPasscodeAdmin = RESULTS.strPasscodeAdmin)
AND (ProcVsSub.strCFICode = RESULTS.strCFICode))
INNER JOIN
tbl_000_010_MAIN_REPORT_INFO as REPORTS ON (RESULTS.lngPCC_ID =
REPORTS.lngPCC_ID)
AND (RESULTS.lngProcedure_ID = REPORTS.lngProcedure_ID)
AND (RESULTS.lngMainReport_ID = REPORTS.idMainReport_ID)
AND (RESULTS.strPasscodeAdmin = REPORTS.strPasscodeAdmin)
AND (RESULTS.strCFICode = REPORTS.strCFICode)
WHERE
(((RESULTS.lngProcedure_ID) = 143)
AND ((RESULTS.dtmExpireDate) IS NOT NULL)
AND ((RESULTS.strCFICode) = 'ems'))
GROUP BY RESULTS.lngMainReport_ID, RESULTS.lngLocationGroupSub_ID
ORDER BY (REPORTS.dtmReportCompleted) DESC;
SELECT t.*
FROM tmpMaxLookupResults AS t
JOIN (
SELECT lngLocationGroupSub_ID,
MAX(dtmReportCompleted) AS max_date_completed
FROM tmpMaxLookupResults
GROUP BY lngLocationGroupSub_ID ) AS dt
ON dt.lngLocationGroupSub_ID = t.lngLocationGroupSub_ID AND
dt.max_date_completed = t.dtmReportCompleted
enter code here
Try this
SELECT
tn.*
FROM
tableName tn
RIGHT OUTER JOIN
(
SELECT
groupId, MAX(date_completed) as max_date_completed
FROM
tableName
GROUP BY
groupId
) AS gt
ON
(gt.max_date_completed = nt.date_completed AND gt.groupId = nt.groupId)
You can use the following SQL.
select * from table1 order by date_completed desc Limit 1;
Use Order By
SELECT *
FROM table_name
ORDER BY your_date_column_name
DESC
LIMIT 1
In a Derived Table, get the maximum date_completed value for every group_id.
Join this result-set back to the main table, in order to get the complete row corresponding to maximum date_completed value for every group_id
Try the following query:
SELECT t.*
FROM your_table_name AS t
JOIN (
SELECT group_id,
MAX(date_completed) AS max_date_completed
FROM your_table_name
GROUP BY group_id
) AS dt
ON dt.group_id = t.group_id AND
dt.max_date_completed = t.date_completed

Filter condition on multiple Join / Inner Join SQL

I'm trying to perform a SQL query with the best possible performance.
First of all I want to randomly pick among the 30000 results a city then JOIN the results another table with the condition
ON `r1`.`ville_nom_reel` = `r3`.`full_name`
(Based on the same city name).
To this query I would like to add a filter to display only the results of which
r1`.`ville_population_2012` > 10000
Here is my main query: run in approximately 0.010 sec.
SELECT * FROM `inspitravel`.`villes_france_free` AS `r1`
JOIN (SELECT CEIL(RAND() * (SELECT MAX(`ville_id`) FROM `inspitravel`.`villes_france_free`)) AS `ville_id` ) AS `r2` USING (`ville_id`)
INNER JOIN `inspitravel`.`villes_booking` AS `r3`
ON `r1`.`ville_nom_reel` = `r3`.`full_name`
How do I filter these results with this condition please?
`r1`.`ville_population_2012` > 10000
I would start with a query that works:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff
WHERE ville_population_2012 > 10000
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;
You can improve the performance of this query with an index on villes_france_free(ville_population_2012).
Then, a safe way to reduce the run-time of this query is to use rand() in the WHERE clause. For instance, you can use this to reduce the size of the sort by about 90%:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff
WHERE ville_population_2012 > 10000 AND
rand() < 0.1
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;
However, the exact value to choose depends on the number of matching towns.
Something like this would normally work:
SELECT *
FROM (SELECT vff.*
FROM inspitravel.villes_france_free vff CROSS JOIN
(SELECT COUNT(*) as cnt FROM inspitravel.villes_france_free vff WHERE ville_population_2012 > 10000
) x
WHERE ville_population_2012 > 10000 AND
(cnt < 100 OR rand() < 0.1 * cnt)
ORDER BY rand()
LIMIT 1
) vff JOIN
inspitravel.villes_booking vb
ON vff.ville_nom_reel = vb.full_name;

Check if SELECT statement with LIMIT returned all rows

Is there a way to check if a SELECT statement with a LIMIT returned all possible rows for example i have LIMIT 50 but i have 64 rows it should add false and if i have 28 rows it should add true. I think i can achieve this with php by doing a something like this but is it possible with SQL only?
$sql= "(SELECT * FROM tbl_group_message WHERE gid = ".$gid." ORDER BY mid DESC LIMIT ".$more.") ORDER BY mid ASC";
$messages = mysqli_query($dbc,$sql);
$row_cnt1 = mysqli_num_rows($messages);
$sql = "(SELECT COUNT(*) FROM tbl_group_message WHERE gid = ".$gid." ORDER BY mid DESC) ORDER BY mid ASC";
$messages = mysqli_query($dbc,$sql);
$row_cnt2 = mysqli_num_rows($messages);
if(row_cnt1 < $row_cnt2){
$allinlimit = true;
}
else{
$allinlimit = false;
}
You can use SQL_CALC_FOUND_ROWS and FOUND_ROWS:
$sql= "SELECT SQL_CALC_FOUND_ROWS * FROM tbl_group_message WHERE gid = ".$gid." ORDER BY mid DESC LIMIT ".$more." ORDER BY mid ASC";
Then run the query SELECT FOUND_ROWS() as the next query to the database.
More information is in the documentation.
EDIT:
As the OP points out, COUNT(*) seems to be faster (in this case).

SQL join and get another column

I'm trying to join two tables so I can easily order it, as one contains the names of items and the other doesn't. The tables:
user_games: UGID, UID, APPID, playtime
games_steam: APPID, name
my SQL so far:
SELECT user_games.*
FROM user_games
JOIN games_steam ON user_games.APPID = games_steam.APPID
WHERE user_games.UID = '76561197996836099'
GROUP BY user_games.APPID
ORDER BY games_steam.name ASC
LIMIT 0, 30
Just no idea how to get the name column into this aswell.
Is this what you are looking for?
SELECT user_games.*, games_steam.name
FROM user_games
JOIN games_steam
ON user_games.APPID = games_steam.APPID
WHERE user_games.UID = '76561197996836099'
GROUP BY user_games.APPID
ORDER BY games_steam.name ASC
LIMIT 0, 30