I have 2 tables: "shares" and "pending_share_changes". The "shares" table has the following columns:
share_ID, asset_ID, member_ID, percent_owner, is_approved
pending_share_changes has the following columns:
share_change_ID, asset_ID, member_ID, percent_owner, is_approved, requested_by
I have a form (php) which lists the pending changes which the members have to approve or deny. Everything works fine unless the member has no existing shares, which means there is no record in the "shares" table for them. The query I am using to view the pending share changes is as follows:
SELECT p.share_change_ID, assets.asset_desc, assets.asset_value, shares.percent_owner AS
percent_owner_old, p.percent_owner
FROM pending_share_changes as p
inner join assets on assets.asset_ID = p.asset_ID
inner join shares on shares.asset_ID = p.asset_ID AND shares.member_ID = p.member_ID
INNER JOIN orgs ON orgs.org_ID = assets.org_ID
WHERE orgs.org_ID = '$org_ID' AND p.member_ID = '$member_ID' AND p.is_approved = '0'
I tried using IFNULL(shares.percent_owner, 0) AS percent_owner_old but that didn't work. The query returns no results. I would like to have the percent_owner_old column display a "0" if there is no record in the shares table.
Thanks.
Try changing your join to shares from an INNER JOIN to a LEFT JOIN.
SELECT ....
FROM pending_share_changes p
....
LEFT JOIN shares ON shares.asset_ID = p.asset_ID AND shares.member_ID = p.member_ID
This means "for every member_ID and asset_ID in p, join it to the matching row in shares. If the member_ID/asset_ID exists in p but not shares, make a row anyway and set the corresponding values to NULL".
The INNER JOIN means to only show joined rows where the relevant record exists in both tables.
Then you can combine with the IFNULL(shares.percent_owner,0) AS percent_owner_old.
Related
table posts
table users
how would i count posts for specific user logged in. for example when user with id 3 is logged in it should show me 4 posts
I already did it for total posts count:
<?php
$post_query1 = "SELECT count(*) AS total FROM posts ";
$post_result1 = mysqli_query($db, $post_query1);
$post1 = mysqli_fetch_array($post_result1);
?>
Try below example :
select count(*) as total from user as u inner join post as p on p.id_user = u.id_user AND u.id_user = 3
If you want to get only the posts count for the particular user, say user with id = 3, your query should be this:
$query = "SELECT count(*) AS total FROM posts WHERE id_users = 3";
But if you want to get both the posts count as well as the user information and other post information, you will have to run a join query on both the users and posts table. Your query would now become:
$query = "SELECT u.*, p.*, count(p.id_posts) FROM users AS u JOIN posts AS p ON u.id_users = p.id_users WHERE p.id_users = 3";
Some Useful Notes
p.* - * is a wildcard character that means get all the columns in the posts table
u.* - * is a wildcard that means get all the columns in the users table
posts as p - AS is for aliasing. So, we are giving posts table a temporary name.
Here are the different types of the JOINs in SQL:
(INNER) JOIN: Returns records that have matching values in both tables
LEFT (OUTER) JOIN: Return all records from the left table, and the matched records from the right table
RIGHT (OUTER) JOIN: Return all records from the right table, and the matched records from the left table
FULL (OUTER) JOIN: Return all records when there is a match in either left or right table
Note: It is necessary that you have to join two/more tables only with the help of foreign key. Without the foreign key is is meaningless to join two or more tables
Reference 1: https://www.w3schools.com/sql/sql_join.asp
Reference 2: https://www.tutorialspoint.com/mysql/mysql-using-joins.htm
As per the Question what you have asked to join the tables
Query:
SELECT * FROM TABLE 1 JOIN TABLE 2 ON TABLE1.id = TABLE2.id WHERE TABLE2.ID=3
Kindly replace TABLE1 & TABLE2 with the Tables that are to be joined and the id with the foreign key what you have specified in the Table.
Hope so this might be helpful for you to write your own code in future. Happy Coding :)
You have only to use a simple join.
SELECT count(*)
FROM USER u,
post p
WHERE p.id_user = u.id_user
AND u.id_user = 3
I have a query that looks up people's full names based on their record ID's in a table called users. The full names are tied to their roles in another table (table1). This requires multiple joins to the users table:
SELECT table1.id, users.full_name AS "Requester",
users.full_name AS "Approver,"
users.full_name AS "Ordered By",
users.full_name AS "Received By"
FROM table1
JOIN users AS users
ON table1.requester_id = users.id
JOIN users AS users2
ON table1.approver_id = users2.id
JOIN users AS users3
ON table1.ordered_by = users3.id
JOIN users AS users4
ON table1.received_by = users4.id
WHERE table1.deleted_record !=1;
The problem I'm having is with ordered_by and received_by. Often, they don't yet exist, because the order has neither been ordered nor received, so the ID for each can be 0, which has no corresponding value in the userstable. When I run this query, I should get back all 475 records that exist, but I only get back 365, because of those 0 values. How can I modify this query to make sure all rows are returned, even if ordered_by and/or received_by = 0?
First, your primary table driving the query should be table1. Then, you are using JOIN instead of LEFT JOIN. LEFT JOIN will give you a null result if no link, but not fail. In which case, you might have to use an IF for your fields value
SELECT table1.id, req.full_name AS "Requester",
app.full_name AS "Approver",
ordr.full_name AS "Ordered By",
rec.full_name AS "Received By"
FROM table1
LEFT JOIN users AS req
ON table1.requester_id = req.id
LEFT JOIN users AS app
ON table1.approver_id = app.id
LEFT JOIN users AS ordr
ON table1.ordered_by = ordr.id
LEFT JOIN users AS rec
ON table1.received_by = rec.id
WHERE table1.deleted_record !=1;
This should do it
You are looking for left join:
SELECT t1.id, ur.full_name AS "Requester",
ua.full_name AS "Approver,"
uo.full_name AS "Ordered By",
urv.uo AS "Received By"
FROM table1 t1 LEFT JOIN
users ur
ON t1.requester_id = ur.id LEFT JOIN
users ua
ON t1.approver_id = ua.id LEFT JOIN
users uo
ON t1.ordered_by = uo.id LEFT JOIN
users urv
ON t1.received_by = urv.id
WHERE t1.deleted_record <> 1;
Note that I changed the aliases on the users references from fairly meaningless u1, u2, etc. to ua, uo, and so on. Also, these need to be used in the SELECT to get the right full name.
I have a table called events and I am doing a select on this table to display a grid with the select results.
The events table has a column called s_code. The s_code value comes from either the suppliers or members table.
How would I do a single JOIN that checks the suppliers and members table to get the code's name without having to do a LEFT JOIN on both members and suppliers tables like my query below. Basically I only want to have b.s_name where I have both b.s_name and c.s_name at the moment.
SELECT a.s_id, b.s_name, c.s_name, a.s_date,
a.s_description, d.s_name, a.s_actiondate,
e.s_name, a.s_emailed, a.s_status
FROM events AS a
LEFT JOIN members AS b ON a.s_code = b.s_code
LEFT JOIN suppliers AS c ON a.s_code = c.s_code
LEFT JOIN webuser AS d ON a.s_userid = d.s_ai
LEFT JOIN webuser AS e ON a.s_actionuserid = e.s_ai
WHERE a.s_status = 'A'
AND a.s_userid = '1'
AND a.s_transactionstatus = 'A'
Just coalesce the two columns into one, if the first is non null return that, otherwise the second;
SELECT a.s_id, COALESCE(b.s_name, c.s_name) s_name, a.s_date, ...
I have a MYSQL query who have to list all post i want it to post. But it dont do it. It shows posts when i have more then one post in the table "meaOrder" with the same "ordCode". But when i have only on post in meaOrder, i don't show it. What can i do?
SELECT koden, wish, rnamn, bild, pris, cname, onsktext
FROM (
SELECT m.wishText as onsktext, m.meaOID as midn, m.ordcode as koden, w.wish as wish, r.meaName as rnamn, r.meaImg as bild,
r.meaPrice as pris, k.catName as cname from cats k, meals r, wishes w,
meaOrder m
join orders c on c.ordNR=4401
WHERE c.ordStatus=1 AND m.ordNR=c.ordNR AND m.meaID=r.meaID AND m.wishesID=w.id
AND r.catID=k.catID
) T
GROUP BY koden, rnamn, bild, pris, cname
ORDER BY midn DESC
TABLE orders
http://grab.by/m74E
TABLE meaOrder http://grab.by/m74Q
Try replacing the JOIN with RIGHT JOIN in this case. The difference is explained at JOIN Syntax page in MySQL docs . In short - JOIN returns row only if there are corresponding rows in both joined tables (inner join). LEFT JOIN / RIGHT JOIN return all rows from one of the tables and corresponding row if it exists from the other table (those are outer joins)
Do you need a subselect?
This seems to cover it:-
SELECT m.ordcode AS koden, w.wish AS wish, r.meaName AS rnamn, r.meaImg AS bild, r.meaPrice AS pris, k.catName AS cname, m.wishText AS onsktext
FROM cats k
INNER JOIN meals r ON r.catID = k.catID
INNER JOIN meaOrder m ON m.meaID = r.meaID
INNER JOIN wishes w ON m.wishesID = w.id
INNER JOIN orders c ON m.ordNR = c.ordNR
WHERE c.ordStatus = 1
AND c.ordNR = 4401
GROUP BY m.ordcode, r.meaName, r.meaImg, r.meaPrice, k.catName
ORDER BY midn DESC
I'm working on displaying the achievements from my minecraft server on my website.
But I can't get it to work.
function achievements() {
global $id;
$sql="SELECT * FROM achievements
INNER JOIN stats ON achievements.type=stats.type
INNER JOIN stats ON achievements.block=stats.block
INNER JOIN stats ON achievements.data=stats.data
INNER JOIN stats ON achievements.value=stats.value
WHERE player_id = $id";
$result=mysql_query($sql) or die(mysql_error());
$rows=mysql_fetch_array($result);
}
Will I be able to use $rows['achievements.type']; and $rows['stats.type']; to get the column "type" from the selected table, or is there a another way to do it?
The column and table names are defined by the plugin I use, so the names can't be changed.
the reason why it is not working is because (in my own opinion) the server is a little confused on where how it will handle the columns names properly. In order it to work, add an alias on every table that has the same name that you want to join as well as the columns, eg
SELECT achievements.*,
a.Name as TypeName,
b.Name AS BlockName,
c.Name as DataName,
d.Name AS ValueName
FROM achievements
INNER JOIN stats a ON achievements.type = a.type
INNER JOIN stats b ON achievements.block = b.block
INNER JOIN stats c ON achievements.data = c.data
INNER JOIN stats d ON achievements.value = d.value
WHERE player_id = $id
assuming you want to get the names for every specific columns.
Give the columns you want to have while you SELECT them an alias as example:
SELECT `achievements`.`type` AS `Achieve-Type`
FROM `achievements`
Now you can get the values like this: $rows['Achieve-Type'];
It's easier to alias the table names with...
SELECT * FROM achievements AS ac INNER JOIN stats as st
You could even alias the results if you wish so they are more distinguishable when you select them from $rows