Count rows in PHP - php

I have a query that grabs a bunch of diffrent tables using LEFT JOIN, and I was wondering if I could incorporate another table, but only count the values in it.
The problem
When I try to use COUNT(row_id) in the query with everything else, it only returns the count and nothing anything else.
$query = "
SELECT COUNT(subscriptions.sub_id) AS total_subscriptions,
postings.posting_id,
postings.posting_headline,
postings.posting_body,
postings.timestamp,
users.user_name
FROM postings
LEFT JOIN users ON postings.user_id = users.user_id
LEFT JOIN subscriptions ON postings.group_id = subscriptions.group_id
WHERE postings.group_id='" . $group['group_id'] . "'
ORDER BY postings.posting_id DESC
";
How can I fix this?

Add an explicit GROUP BY clause to the query.

Related

How to fetch data from a joined query in PHP

I've a joined query in PHP, which I wanted to join 2 databases VIA the user ID, but I want to be able to fetch data from both tables (users & user_stats), although it's not letting me output any data from the user_stats table, which is leaving me to believe there's a error in my query..
Hence this being my first time using joined tables, could someone please guide me in the correct direction, so far I have:
$getMembers3 = dbquery("SELECT users.id, users.look, users.username
FROM users
JOIN user_stats
ON users.id = user_stats.id
WHERE users.rank < 2 ORDER BY user_stats.Respect DESC LIMIT 10");
Which I am trying to fetch Respects from user_stats VIA:
while ($member2 = mysql_fetch_assoc($getMembers3))
{
echo $member2['user_stats.Respect'] . '<br>';
echo $member2['username'] . '<br>';
}
Although it allows me to view their username from the users table, it won't allow me to view the user_stats.Respect. If someone could enlighten me in the right direction that'd be fantastic.
I always get confused when selecting from mutliple tables and this is how I generally resolve my confusion:
$getMembers3 = dbquery("SELECT users.id as id, users.look as look, users.username as username, user_stats.Respect as respect
FROM users
JOIN user_stats
ON users.id = user_stats.id
WHERE users.rank < 2 ORDER BY user_stats.Respect DESC LIMIT 10");
This way you know what the column names are expected to be. Sidenote, the result set will not have dots in the array keys.
Then you can access results from:
while ($member2 = mysql_fetch_assoc($getMembers3))
{
echo $member2['respect'] . '<br>';
echo $member2['username'] . '<br>';
}
Change your query adding the field in your select statement:
$getMembers3 = dbquery("SELECT users.id, users.look, users.username,user_stats.Respect
FROM users
JOIN user_stats
ON users.id = user_stats.id
WHERE users.rank < 2 ORDER BY user_stats.Respect DESC LIMIT 10");
As a side note you are using a deprecated api to access database that have been removed in PHP 7. Consider switching to PDO and prepared statements.

PHP PDO Multiple Table join

I have multiple tables and I want to access the fields in a specific table. Here are the table schemas:
Each tbl_acct has one tbl_unit. A tbl_unit has many tbl_groups and a tbl_groupcontact consist of the contacts and the related group. Every time I log in, I set a session where $_SESSION['unitid'] = $row['unitid'];.
What I wanted to do is to access the fields in the tbl_contacts. For now my code is here:
$data = $conn->prepare("SELECT * FROM tbl_groups LEFT JOIN tbl_groupcontact ON tbl_groups.id=tbl_groupcontact.group_id WHERE tbl_groups.unitid = ?");
$data->execute(array($_SESSION['unitid']));
foreach ($data as $row) {
echo $row['fname'] . " " . $row['lname']. "<br />";
}
As you can see, I can related the tbl_groups and tbl_groupcontact in my code however, I can't get the fields in the tbl_contacts. Am I missing something here? Any help would be much appreciated.
You need to join another table.
SELECT tbl_contacts.*
FROM tbl_groups
INNER JOIN tbl_groupcontact ON tbl_groupcontact.group_id = tbl_groups.id
INNER JOIN tbl_contacts ON tbl_contacts.id = tbl_groupcontact.contact_id
WHERE tbl_groups.unitid = ?
No need for (slower) LEFT JOIN btw - use it when you want to retrieve records from (left-side) table even when there's no match found in joined (right-side) table (it's columns will be filled with nulls in this case).

How to Output the results of a MySQL query that used aliases?

I have two primary MySQL tables (profiles and contacts) with many supplementary tables (prefixed by prm_). They are accessed and manipulated via PHP.
In this instance I am querying the profiles table where I will retrieve an Owner ID and a Breeder ID. This will then be referenced against the contacts table where the information on the Owners and Breeders is kept.
I received great help here on another question regarding joins and aliases, where I was also furnished with the following query. Unfortunately, I am having huge difficulty in actually echoing out the results. Every single site that deals with Self Joins and Aliases provide lovely examples of the queries - but then skip to "and this Outputs etc etc etc". How does it output????
SELECT *
FROM (
SELECT *
FROM profiles
INNER JOIN prm_breedgender
ON profiles.ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN contacts ownerContact
ON profiles.ProfileOwnerID = ownerContact.ContactID
LEFT JOIN prm_breedcolour
ON profiles.ProfileAdultColourID = prm_breedcolour.BreedColourID
LEFT JOIN prm_breedcolourmodifier
ON profiles.ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
) ilv LEFT JOIN contacts breederContact
ON ilv.ProfileBreederID = breederContact.ContactID
WHERE ProfileName != 'Unknown'
ORDER BY ilv.ProfileGenderID, ilv.ProfileName ASC $limit
Coupled with this is the following PHP:
$owner = ($row['ownerContact.ContactFirstName'] . ' ' . $row['ownerContact.ContactLastName']);
$breeder = ($row['breederContact.ContactFirstName'] . ' ' . $row['breederContact.ContactLastName']);
All details EXCEPT the contacts (gender, colour, etc.) return fine. The $owner and $breeder variables are empty.
Any help in settling this for me would be massively appreciated.
EDIT: My final WORKING query:
SELECT ProfileOwnerID, ProfileBreederID,
ProfileGenderID, ProfileAdultColourID, ProfileColourModifierID, ProfileYearOfBirth,
ProfileYearOfDeath, ProfileLocalRegNumber, ProfileName,
owner.ContactFirstName AS owner_fname, owner.ContactLastName AS owner_lname,
breeder.ContactFirstName AS breeder_fname, breeder.ContactLastName AS breeder_lname,
BreedGender, BreedColour, BreedColourModifier
FROM profiles
LEFT JOIN contacts AS owner
ON ProfileOwnerID = owner.ContactID
LEFT JOIN contacts AS breeder
ON ProfileBreederID = breeder.ContactID
LEFT JOIN prm_breedgender
ON ProfileGenderID = prm_breedgender.BreedGenderID
LEFT JOIN prm_breedcolour
ON ProfileAdultColourID = prm_breedcolour.BreedColourID
LEFT JOIN prm_breedcolourmodifier
ON ProfileColourModifierID = prm_breedcolourmodifier.BreedColourModifierID
WHERE ProfileName != 'Unknown'
ORDER BY ProfileGenderID, ProfileName ASC $limit
Which I could then output by:
$owner = ($row['owner_lname'] . ' - ' . $row['owner_fname']);
Many Thanks to All!
I guess you're using the mysql_fetch_array or the mysql_fetch_assoc-functions to get the array from the result-set?
In this case, you can't use
$row['ownerContact.ContactFirstName']
as the PHP-Docs read:
If two or more columns of the result have the same field names, the
last column will take precedence. To access the other column(s) of the
same name, you must use the numeric index of the column or make an
alias for the column. For aliased columns, you cannot access the
contents with the original column name.
So, you can either use an AS in your SQL-query to set other names for the doubled rows or use the numbered indexes to access them.
This could then look like this:
Using AS in your Query
In your standard SQL-query, the columns in the result-set are named like the columns which their values come from. Sometimes, this can be a problem due to a naming-conflict. Using the AS-command in your query, you can rename a column in the result-set:
SELECT something AS "something_else"
FROM your_table
This will rename the something-column to something_else (you can leave the ""-quotes out, but I think it makes it more readable).
Using the column-indexes for the array
The other way to go is using the column-index instead of their names. Look at this query:
SELECT first_name, last_name
FROM some_table
The result-set will contain two columns, 0 ==> first_name and 1 ==> last_name. You can use this numbers to access the column in your result-set:
$row[0] // would be the "first_name"-column
$row[1] // would be the "last_name"-column
To be able to use the column-index, you'll need to use mysql_fetch_row or the mysql_fetch_assoc-function, which offers an associative array, a numeric array, or both ("both" is standard).
you need to replace the * with the data you need , and the similar ones you have to make aliases too :
ownerContact.ContactFirstName as owner_ContactFirstName
and
breederContact.ContactFirstName as breeder_ContactFirstName .
like this :
select ownerContact.ContactFirstName as owner_ContactFirstName , breederContact.ContactFirstName as breeder_ContactFirstName from profiles join ownerContact ... etc
in this way you will write :
$owner = ($row['owner_ContactFirstName'] . ' ' . $row['owner_ContactLastName']);
$breeder = ($row['breeder_ContactFirstName'] . ' ' . $row['breeder_ContactLastName']);
You cannot specify table alias when you access row using php. Accessing it by $row['ContactFirstName'] would work if you didn't have 2 fields with the same name. In this case whatever ContactFirstName appears second overwrites the first.
Change your query to use fields aliases, so you can do $owner = $row['Owner_ContactFirstName'].
Another option I'm not 100% sure is to access field by index, not by name(e.g. $owner=$row[11]). Even if it works I don't recommend to do so, you will have a lot of troubles if change your query a bit.
On outer select You have only two tables:
(inner select) as ilv
contacts as breederContact
there is no ownerContact at all

How to use the OR statement in MySQL while using the LIKE search statement

I am trying to create a good little search statement that searches muitple fields using the with different search terms depending on what is returned. I am basiclly setting an order in which I want to search if one search term is not found try the next one. However I am using a WHERE clause to seperate search only one type of data. Currently I am getting some strange results returned because I don't think my order is correct, it seems that my WHERE clause is being ignored.
here is my statement (I am usig PHP):
mysql_query("SELECT * FROM item AS i LEFT JOIN country AS c ON i.country_id = c.country_id WHERE i.item_status = 'active' AND (i.item_name LIKE '%".$_SESSION['item']."%') OR i.item_description LIKE '%".$_SESSION['description']."%' OR i.item_name LIKE '%".$_SESSION['description']."%' ");
Thank you in advance.
Why don't you use full-text search feature?
Need to alter table structure for create fulltext search index.
ALTER TABLE item ADD FULLTEXT (item_name, item_description);
Then your queries turns to:
mysql_query("
SELECT * FROM item AS i LEFT JOIN country AS c ON i.country_id = c.country_id
WHERE i.item_status = 'active' AND
MATCH (i.item_name, i.item_description)
AGAINST (" . $_SESSION['item'] . " " . $_SESSION['description'] . ");
");
Simple, accurate, and faster.
Move the right parenthesis to the end of the statement:
SELECT *
FROM item AS i LEFT JOIN country AS c
ON i.country_id = c.country_id
WHERE i.item_status = 'active'
AND (i.item_name LIKE '%".$_SESSION['item']."%'
OR i.item_description LIKE '%".$_SESSION['description']."%'
OR i.item_name LIKE '%".$_SESSION['description']."%')
It is your parentheses in the wrong place. Here is the correct code:
mysql_query("SELECT * FROM item AS i LEFT JOIN country AS c ON i.country_id = c.country_id WHERE i.item_status = 'active' AND (i.item_name LIKE '%".$_SESSION['item']."%' OR i.item_description LIKE '%".$_SESSION['description']."%' OR i.item_name LIKE '%".$_SESSION['description']."%')");
The OR operator has lower precedence than the AND operator. http://dev.mysql.com/doc/refman/4.1/en/operator-precedence.html
Put all the ORs inside parentheses (one that contains all of them, not one for each of them ;) ).

Returning data from multiple tables in one query even if secondary tables do not apply

I have an issue getting data from three tables, which I want to return using one query.
I've done this before using a query something like this one:
$query = mysql_query("SELECT
maintable.`id`,
maintable.`somedata`,
maintable.`subtable1_id`,
subtable1.`somedata`,
subtable1.`subtable2_id`,
subtable2.`somedata`
FROM
`maintable` maintable,
`subtable1` subtable1,
`subtable2` subtable2
WHERE
maintable.`somedata` = 'some_search' AND
subtable1.`id` = maintable.`subtable1_id` AND
subtable2.`id` = subtable1.`subtable2_id`
")or die(mysql_error());
The problem this time is that the extra details might not actually apply. I need to return all results that match some_search in maintable, even if there is no subtable1_id specified.
I need something that will go along the lines of
WHERE
maintable.`somedata` = 'some_search'
AND IF maintable.`subtable1_id` IS NOT NULL (
WHERE subtable1.`id` = maintable.`subtable1_id` AND
subtable2.`id` = subtable1.`subtable2_id`
)
As you will probably guess, I am not an advanced mysql user! Try as I might, I cannot get the syntax right, and I have had no luck searching for solutions on the web.
Any help much appreciated!
It seems like the basic distinction you're looking for is between an INNER JOIN and a LEFT JOIN in MySQL.
An INNER JOIN will require a reference between the two tables. There must be a match on both sides for the row to be returned.
A LEFT JOIN will return matches in both rows, like an INNER, but it will also returns rows from your primary table even if no rows match in your secondary tables -- their fields will be NULL.
You can find example syntax in the docs.
If I got this right, you need to use MySQL LEFT JOIN. Try this:
SELECT
m.id,
m.somedata,
m.subtable1_id,
s1.somedata,
s1.subtable2_id,
s2.somedata
FROM
maintable m
LEFT JOIN
subtable1 s1
ON
m.subtable1_id = s1.id
LEFT JOIN
subtable2 s2
ON
s1.subtable2_id = s2.id
WHERE
m.somedata = 'some search'
This will return the data of maintable even if there's no equivalent data in subtable1 or 2 OR data of maintable and subtable1 if there's no equivalent data in subtable2.
How about this:
WHERE
maintable.`somedata` = 'some_search'
AND (maintable.`subtable1_id` IS NULL OR (
subtable1.`id` = maintable.`subtable1_id` AND
subtable2.`id` = subtable1.`subtable2_id` )
)
Keep in mind that this will result in a cross product of subtable1 and subtable2 with maintable when subtable1_id is NULL.

Categories