I have a query that returns the count of active and inactive posts, plus the specific post details. Here's the query
$fetch = mysql_query("SELECT SQL_CALC_FOUND_ROWS * FROM
(SELECT DISTINCT propertyID, streetAddress, city FROM residence.property
WHERE residence.contact.contactEmailAddress1 ='$contactEmailAddress1' AND activePosting = '0') inactposts,
(SELECT FOUND_ROWS() AS 'inactiveCount') inact,
(SELECT DISTINCT propertyID, streetAddress, city FROM residence.property
INNER JOIN contact ON residence.contact.ContactID = residence.property.ContactID
WHERE residence.contact.contactEmailAddress1 ='$contactEmailAddress1' AND activePosting = '1') actposts,
(SELECT FOUND_ROWS() AS 'activeCount') act;")
or die('<li class=error>Ooops</li>'.mysql_error());
The query works in my web page. In MySQL Workbench it returns things looking like:
propID address city inactCount propID address city actCount
366 110 Main Street Perinton 1 352 3 Some Place Perinton 3
366 110 Main Street Perinton 1 353 5 Joe Place Perinton 3
366 110 Main Street Perinton 1 356 111 Main Perinton 3
The issue for me is the 2 parts of the sub-query results don't have an identifier (that I can find), so in the HTML constructed by the PHP server, I can't separate the lists into into inactive posts (inactposts) and active posts (actposts). Currently the HTML only returns the list of active posts. I've tried putting "inactposts", the name of the temporary table, in various places and I just get error messages
Here's the PHP doing the HTML construction:
if( mysql_num_rows($fetch) ) {
while ($row = mysql_fetch_array($fetch)) {
$inactiveCount = $row["inactiveCount"];
$activeCount = $row["activeCount"];
$storedStreetAddress = $row["streetAddress"];
$storedCity3 = $row['city3'];
$error_NumberInactives = "<ul>You have $activeCount active posts and $inactiveCount inactive posts.</ul>";
$error_List_Actives = "<li>Your $activeCount active posts are:</li>";
$errorMessages[0] = $error_NumberInactives;
$errorMessages[1] = $error_List_Actives;
$errorMessages[] = "<li> $storedStreetAddress, $storedCity3 </li>";
}else{ //error message}
How can I construct separate lists of sub-query results from this query? Or do I need a different query?
You'll need another query without the aggregation if you want the individual rows.
Alternately, select all of the posts (with details) in one query and parse the result in php to count the number of active and inactive:
SELECT DISTINCT propertyID, streetAddress, city, activePosting FROM residence.property
INNER JOIN contact ON residence.contact.ContactID = residence.property.ContactID
WHERE residence.contact.contactEmailAddress1 ='$contactEmailAddress1'
p.s. I assume you have sanitized your inputs outside of the provided code, otherwise you need to do that.
Related
I stumbled upon a query that I have never done until now.
Before asking the question I looked for if another user had had the same need as me but nothing.
My goal is very simple:
having two tables:
collaboratori (collaborators)
invite (invitations)
I have to count how many invitations the collaborators have made.
table structure of collaboratori:
ID_Collaboratori | cod_manager
37 4675
150 6675
3 6575
table structure of inviti:
invite_id | invite_code_manager
37 6675
39 6575
40 4675
41 6675
if I execute the join obviously I access the two tables in this way:
$q_stats_prod_manager = $connessione->prepare("
SELECT * FROM invite
LEFT JOIN collaboratori
ON collaboratori.cod_manager = invite.invite_code_manager ");
$q_stats_prod_manager->execute();
$r_stats_prod_manager = $q_stats_prod_manager->get_result();
my need lies in showing in a table:
show me for each manager who has his cod_manager inside the inviti table, the number of times he sent them.
Name Surname Manager 1 | Number of invite: 200
Name Surname Manager 2 | Number of invite: 50
Name Surname Manager 3 | Number of invite: 10
not limiting myself to just one counter but also being able to access other table values like any join
I take the liberty of putting the answer that was partially written by another user, adding a detail and explanation for future users. The resolution query for this case is the same:
$q_stats_prod_manager = $connessione->prepare("
SELECT count(invite.invite_id)
/*name of what you want to call the result you will see in the while*/
AS result_count, /*you can call this value whatever you want*/
/*Start | Values of the tables you are interested in selecting*/
collaboratori.nome,
collaboratori.data_registrazione,
invite.invite_code_manager
/*End | Values of the tables you are interested in selecting*/
FROM collaboratori
LEFT JOIN invite
ON invite.invite_code_manager = collaboratori.cod_manager group by invite.invite_code_manager
");
$q_stats_prod_manager->execute();
$r_stats_prod_manager = $q_stats_prod_manager->get_result();
$count_invite_manager=mysqli_fetch_array($r_stats_prod_manager);
$number_of_invite_manager = $count_invite_manager[0];
Select the id of the table you want to count
Give a name you wish you want to name the counted result
Select the values of the tables on which you will perform the join you want to view
Join the tables
Show the result with while
Code while:
<?php while($rowstatspm = mysqli_fetch_assoc($r_stats_prod_manager)){ ?>
<!-- this is the fancy name you associated with your query when you wrote: AS nameofwhatyouwant -->
<?php echo $rowstatspm['result_count'] ;?>
<?php } ?>
You seem to want aggregation. I assume you want all rows for collaboratori, so that should be the first table for the LEFT JOIN:
SELECT c.cod_manager, COUNT(i.invite_code_manager)
FROM collaboratori c LEFT JOIN
invite i
ON c.cod_manager = i.invite_code_manager
GROUP BY c.cod_manager;
Your question doesn't describe where the name comes from. But those fields should be in both the SELECT and GROUP BY.
SELECT count(invite.invite_id),collaboratori.name FROM collaboratori
LEFT JOIN invite
ON invite.invite_code_manager = collaboratori.cod_manager group by invite.invite_code_manager
► Context : I work in a museum (for real), people come everyday, they buy tickets for themselves (humans) and sometimes they also buy tickets for drinks and foods (objects). There are events, tickets have the same names per event but the prices are different.
► The problem : I have to create a report with 2 results : total sales (visitors + food + drinks) and how many people came (visitors only) for a specific event. Next is an image of the 3 tables in the database, how they relate and some sample data :
Table TICKETS relates to SALES_MAIN through EVENT_ID column.
Table SALES_MAIN relates to SALES_DETAIL through ID→MAIN_ID columns.
Table SALES_DETAIL have a column TICKET_NAME but it's not unique in table TICKETS.
► The question : How to get both results, total sales and human count, for event 555 in one "select" ? I tried next 2 "select" but when I combine them with another INNER JOIN I get cartesian results :
Get detail sales for event 555 :
SELECT sales_detail.* FROM sales_main
INNER JOIN sales_detail ON sales_detail.main_id = sales_main.id
WHERE sales_main.event_id = '555'
Get tickets for event 555 :
SELECT * FROM tickets WHERE tickets.event_id = '555'
Use:
SELECT
SUM(CASE WHEN sd.ticket_name IN ('adult', 'child') THEN sd.quantity
ELSE 0 END) AS total_visitors,
SUM(sd.quantity * t.price) AS total_sales
FROM sales_main sm
JOIN sales_detail sd
ON sd.main_id = sm.id
JOIN ticket t
ON t.event_id = sm.event_id
AND t.ticket_name = sd.ticket_name
WHERE sm.event_id = '555';
Conditional aggregation could also be based on type:
SUM(CASE WHEN t.ticket_type ='human' THEN sd.quantity ELSE 0 END)
I've 4 table for a newsletter. Newsletters, Subscribers, Subscriber Groups and Selected Subscriber Groups. I've choose subscriber groups in campaign edit area, and its save selected groups to tbl_newsletter_groups table like;
tbl_newsletters
NID title details
1 text 1 content 1
2 text 2 content 2
tbl_subscriber_groups
GID group_name
5 group 1
6 group 2
tbl_subscribers
SID GID email name
10 5 sub1#mail.com sub1 name
11 6 sub1#mail.com sub1 name
tbl_newsletter_groups
NGID NID GID
15 1 6
16 1 6
17 1 6
I want to show total selected subscriber count when I list newsletters in my page. My soulution works fine, Im looking for simple and clearly statement, there any faster way available like in single newsletter list statement?
Here my own count style (yes I know its too bad and long way);
$subGID = array();
$list = $myconn->query("SELECT * FROM tbl_newsletters");
while($listRs = $list->fetch_assoc()){
$grps = $myconn->query("SELECT * FROM tbl_newsletter_groups WHERE NID=". $listRs['NID'] ."");
while($grpsRs = $grps->fetch_asscoc()){
$subGID[] = $grpsRs['GID'];
} $grps->free();
$subs = implode(" OR GID=",$subGID);
$count = mysqli_num_rows($myconn->query("SELECT ID FROM tbl_subscribers WHERE GID=". $subs));
echo('Total Selected Subscriber: '.$count);
} $list->free();
Thanks.
The search term you want is "set-based logic".
Your thinking is sound: you need everything from tbl_newsletters, then you need to count results from tbl_subscribers, but in order to get those you need information from tbl_newsletter_groups.
In SQL, that's an indication you want a join. You've already discovered the conditions you need, you just don't know the syntax. A reference manual can help there.
Now you'll have a bunch of records, which you need to smash into a smaller number of records. You need aggregation functions and a GROUP BY clause.
So here's the final query:
SELECT n.NID, n.title, n.details, COUNT(s.SID)
FROM tbl_newsletters AS n
JOIN tbl_newsletter_groups AS g ON n.NID = g.NID
JOIN tbl_subscribers AS s ON g.GID = s.GID
GROUP BY n.NID
I've tried everything to figure this out but I can't get the correct total. My attempts either add all the records and not just the latest ones or I only get the first record.
My first table: hubs
hubID hubName
1 hub1
2 hub2
My second table: hub_reports
reportID hubID date health school
1 1 2012-04-27 467 322
2 2 2012-04-23 267 22
3 1 2012-01-20 176 623
So what you see is 2 tables, one with the organizations name and other info and the second with the reports that each organization submits quarterly. I want to list all the organizations and their latest report. At the bottom of the table I want to add all the available health kits and school kits that are currently available.
Here's the code I'm using right now to display all the organizations and their latest reports.
SELECT * FROM (SELECT hubName, date, health, school FROM hub_reports,
hubs WHERE hub_reports.hubID = hubs.hubID ORDER BY date DESC) AS Total
GROUP BY hubName
This seems to work but when I try the same tactic to get the SUM of the health and school columns I don't get the right answer.
SELECT SUM(health) FROM (SELECT hubName, date, health FROM
hub_reports, hubs WHERE hub_reports.hubID = hubs.hubID ORDER BY date
DESC) AS Total GROUP BY hubName
I tried other using a LEFT JOIN approach that I found on another forum but it didn't seem to work any better. But I maybe I wasn't doing it right.
Please help!
I just encountered a similar problem in a project of mine. A variation of this query worked for me. Hope it is helpful to you.
SELECT hubs.hubName, hub_reports.*,
SUM(hub_reports.health) AS ttl_health,
SUM(hub_reports.school) AS ttl_school
FROM hubs, hub_reports
WHERE hub_reports.hubID = hubs.hubID
GROUP BY hub_reports.hubID
ORDER BY hub_reports.date DESC
Here's the PHP:
$rs = mysql_query( 'SELECT hubs.hubName, hub_reports.*,
SUM(hub_reports.health) AS ttl_health,
SUM(hub_reports.school) AS ttl_school
FROM hubs, hub_reports
WHERE hub_reports.hubID = hubs.hubID
GROUP BY hub_reports.hubID
ORDER BY hub_reports.date DESC' );
$grand_total['school']=0;
$grand_total['health']=0;
while ( $row = mysql_fetch_assoc( $rs ) ){ // Step through each hub
echo "{$row['hubName']} shows {$row['ttl_school']} total school, {$row['ttl_health']} total health";
$grand_total['school'] += $row['ttl_school'];
$grand_total['health'] += $row['ttl_health'];
}
echo "Grand Total School: {$grand_total['school']}, Grand Total Health: {$grand_total['health']}";
You're likely looking for the MAX() function.
Try this:
SELECT h.hubID, h.hubname, MAX(hr.date) as hrdate, SUM(hr.health) as health, SUM(hr.school) as school
FROM hubs h
LEFT JOIN hub_reports hr ON hr.hubID = h.hubID
GROUP BY h.hubID
Edit
You want the MAX date so it only returns the most recent entry (assuming your entries are entered by date, of course).
Hi simple question i guess, but cant figure out how to list the mysql sql the way i want it.
Basiclly in one row I have CityID's I want to be able to pull out the CityID's that == 14 and show them at the top of the return (BUT NOT AS A COUNT)
for e.g
Perth == 15
Melbourne == 14
Preston == 14
Sydney == 13
currently they show like this
Sydney == 13
Perth == 15
Melbourne == 14
Preston == 14
my code
$sth = mysql_query("SELECT users.id as id, users.username as username, profile.defaultpictureid as picture FROM users, userprofiles as profile WHERE online = '1' AND profile.country = ".$this->country." AND profile.state = ".$this->state." AND profile.city = ".$this->city." ORDER BY if (profile.city = 12276,0,1)");
The code above seems to be working now.
However also seems to print out the data twice.
[{"id":"7","username":"A","picture":"0"},{"id":"1","username":"B","picture":"0"},{"id":"1","username":"B","picture":"1"},{"id":"7","username":"A","picture":"1"}]
You're selecting from two tables (users and profiles), but have no specified any kind of relationship between when in your where clause, so what you're getting is the Cartesian product of the two, which is why you're getting the duplicated results.
I'm guessing your query should look something more like this:
SELECT users.id as id, users.username as username, profile.defaultpictureid as picture
FROM users, userprofiles as profile
WHERE
online = 1 AND
profile.country = {$this->country} AND
profile.state = {$this->state} AND
profile.city = {$this->city} AND
users.id = userprofiles.userid <---the join condition for the two tables
ORDER BY if (CityID = 14, 1, 0), profile.city
You can apply an if clause in the sorting
order by if(CityID = 14,0,1)