Inner join in php redbeans - mysql

I have following structure
USER
user_id
name
EVENT
event_id
user_id
event_name
How can I write inner join in redbean?
SELECT * FROM event e join user u on u.user_id = e.user_id
also how can I change Primary key of table schema in redbeans

Try
SELECT u.user_ID, u.name, e.event_id, e.user_id, e.event_name
from user u
inner join event e
on u.user_id=e.user_id
as you can see. You select all the columns from table event. Of course by doing this, it will not include the columns from table user. Thus we will now include all the column you want to display one by one and of course with it's respective alias.

Related

How to count a number from different table when there's no common field?

There are a user table and a user_follow table that describes which user.id is following/followed. I'd like to count the occurrences of that user is following and being followed.
The problem is that user_follow table doesn't have user_id as a foreign key, so I'm not able to join enter image description here the two tables by a common field. I've tried to use LEFT OUTER JOIN on user.id=user_follow.following_user_id and GROUP BY user.id, but it only counts the times of following(followed times is exactly the same as the following, which is not right).
The way to solve this is to join on USER_FOLLOW twice, once for Followed By and once for Following.
You haven't posted the structure of USER_FOLLOW, so this is a guess and you'll need to correct it to fit your schema.
select u.id, u.first_name, u.last_name
, count(f.following_user_id) as following_count
, count(fb.user_id) as followed_by_count
from user u
left_outer join user_follow f on where f.user_id = u.id
left_outer join user_follow fb on where fb.following_user_id = u.id
group by u.id, u.first_name, u.last_name

MySQL Query phpmyadmin

I'm trying to make a SQL query that will search for user id and populate the query with the username.
These are my tables:
Table Names: 'users' and 'schedule'
This is how I want it to look like, where 'schedule' table now shows the username instead of the user's ID
This is the query you are looking for:
SELECT s.REFID, s.jobnum, s.customer, u1.username AS engineer, u2.username AS sales
FROM schedule s, users u1, users u2
WHERE s.engineer=u1.id
AND s.sales=u2.id
You need to reference the users table two separate times, since you are checking in one sub-query for the engineer's username, and then checking in a separate sub-query for the salesperson's username.
Here is a link to an SQLFiddle that shows the result of the query's execution. It matches up with what you were looking for. I hope this helps.
Following Query will give you the expected result:
SELECT
s.refid as refid,
s.jobnum as jobnum,
s.customer as customer,
u_engg.username as engineer,
u_sales.username as sales
FROM
user u_engg join schedule s on u.id = s.engineer join
user u_sale on u_sale.id = s.sales
SELECT s.refid, s.jobnum, s.customer, u.username engineer, u.username sales
FROM schedule s
LEFT OUTER JOIN users u
ON s.engineer = u.id AND s.sales = u.id
It looks like you need to reference the users table two times. One JOIN to get the engineer username, and a second JOIN to get the sales username.
Something like this:
-- return all rows from schedule, and lookup of username where available
SELECT s.REFID
, s.jobnum
, s.customer
, e.username AS engineer
, a.username AS sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
Using a LEFT [OUTER] JOIN ensures that the rows from schedule will be returned when there isn't a matching row in the users table. For example, if you had a NULL in the sales column of a row in schedule, there wouldn't be a matching row in the users table. With an [INNER] JOIN, the row from schedule would not be returned. But the query above does return the row, but with a NULL for the username when matching rows are not found.
If the engineer and sales columns are defined as NOT NULL, and foreign keys are defined and enforced, then the LEFT keyword can be omitted from the query above. In the more general case, where foreign keys are not enforced (e.g. MyISAM) or not defined, or the columns are nullable, we'd generally want the LEFT keywords.
UPDATE
Removing the LEFT keywords from the query will produce a query equivalent to that in the answer from Alvin Lee, which implements INNER JOIN operations.
The query from Alvin Lee will EXCLUDE rows from schedule that have a value in the engineer or sales column that is NULL, or has a value that does not match a value found in the id column of the users table.
To identify if any rows in the schedule table are not being returned by the query using an INNER JOIN, you can run a query that does an anti-join pattern.
-- find rows in schedule that don't have matching row in users
SELECT s.REFID
, s.jobnum
, s.customer
, s.engineer
, s.sales
FROM schedule s
LEFT
JOIN users e
ON e.id = s.engineer
LEFT
JOIN users a
ON a.id = s.sales
WHERE a.id IS NULL
OR e.id IS NULL
try this:
select sc.REFID, sc.jobnum, sc.customer, us.username as engineer, us.username as sales
from schedules as sc
left join users as us on sc.engineer = us.ID and sc.sales = us.ID

MySQL Join table and count distinct users with no reference in another table

I am trying to count users that are NOT referenced in another table... Right now, I have something along the lines of this:
SELECT COUNT(DISTINCT u.id) FROM users u INNER JOIN orders o ON o.assigned!=u.id;
However, it's returning an invalid value. Any suggestions?
Thank you!
I would suggest using a LEFT JOIN between the two tables and filter the rows without a matching id in the orders table:
select count(u.id)
from users u
left join orders o
on o.assigned = u.id
where o.assigned is null
See SQL Fiddle with Demo
Use a left join and count the rows with no match:
SELECT COUNT(*)
FROM users u
LEFT JOIN orders o
ON o.assigned = u.id
WHERE o.assigned IS NULL
An alternative is to use a NOT IN check:
SELECT COUNT(*)
FROM users
WHERE id NOT IN (SELECT distinct(assigned) FROM orders)
However, in my experience the left join performs better (assuming appropriate indexes).
Simply use this query, assuming that the id is unique in users table:
select count(*) From Users as u where u.id not in (select assigned from orders)
an inner join explicitly looks for rows that match so that isn't the way to go if you are looking for non matched records
assuming that ORDERS.ASSIGNED is matched with USER.ID an outer join could return values from both and show when there aren't matches like so
select
u.id,
o.*
from users u
full outer join orders o
on o.assigned = u.id;
if you only want to know which USER.ID don't have an ORDERS record you could also INTERSECT or use NOT IN () eg
select u.id from users u where id not in (select o.assigned from orders.o);
SELECT COUNT(1) FROM users u
WHERE NOT EXISTS (SELECT * FROM orders o WHERE o.assigned=u.id);
Are you wanting a straight count (like you mentioned), or do you need values returned? This will give you the count; if you want other values, you should take one of the other approaches listed above.

MySQL using Group By to limit results

Okay, so I am trying to perform a query that has 4 tables,
users, events, event_roles, user_event_role.
The users can fill multiple roles. What i am trying to do is get a result that looks more like this:
User, event, Role(s)
So if user 'Bill' is associated with event 'Meeting' and 'Bill' Fills multiple roles instead of getting a result like this:
user event role
--------------------------
bill Meeting admin
bill Meeting director
how would I get my result to be like this
user event role role
----------------------------------
bill Meeting admin director
Here is a query that I'm trying to build off of.
Select *
FROM `users` u
LEFT JOIN `event_role` er ON u.user_id = er.user_id
LEFT JOIN `events` e ON er.event_id = e.event_id
The result you seek is not possible.
However there is something close:
SELECT
user,
event,
group_concat(role SEPARATOR ',') as roles
FROM
`users` u
LEFT JOIN `event_role` er
ON u.user_id = er.user_id
LEFT JOIN `events` e
ON er.event_id = e.event_id
GROUP BY u.user_id
which would yield:
user event roles
----------------------
bill Meeting admin,director
In either case you would need to adjust your logic to parse it correctly.
You cannot get such result, because you don't know how many roles there might be (i.e. columns count), but you can use GROUP_CONCAT that way:
SELECT *,
GROUP_CONCAT(event_roles.role SEPARATOR ',') as roles
FROM users
LEFT JOIN event_role USING(user_id)
LEFT JOIN events USING(user_id)
GROUP BY user_id
Using this query you will get all roles concatonated with ,. But be aware of limitation of GROUP_CONCAT, the default value is set to 1024 characters which might not be enough (see my.cnf).
Use Group_concat (http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html) like this.
To show that quickly, I'm using a database from the excellent MySQL intro book by Ben Forta (http://www.forta.com/books/0672327120/), no affiliation.
SELECT v.vend_id, GROUP_CONCAT(p.prod_id)
FROM products p
JOIN vendors v ON v.vend_id= p.vend_id
JOIN orderitems oi ON oi.prod_id = p.prod_id
GROUP BY v.vend_id;

SQL how to select from 2 tables and match them

I have table called users and table called events.
Every user sets is own preferred "area codes".
Every event is set to some area codes, and this information is saved in a table:
events_areas:
area_id BIGINT
event_id BIGINT
I am trying to find a good way to let the user select is own area codes... and then to match it in a select statement with the event area codes.
i tought about doing the same as events_areas and do: users_areas:
area_id BIGINT
user_id BIGINT
But then I dont know how to match them in select statement... ?
Thanks
Assuming the tables you listed, the following would select all events in the users selected area codes.
SELECT u.*, e.*
FROM users u
JOIN users_areas ua
ON u.id = ua.user_id
JOIN events_areas ea
ON ea.area_id = ua.area_id
JOIN events e
ON ea.event_id = e.id
The select statement would look something like this:
SELECT DISTINCT users.*, events.*
FROM users
JOIN users_areas ON users.user_id = users_areas.user_id
JOIN events_areas ON users_areas.area_id = event_areas.area_id
JOIN events ON events_areas.event_id = events.event_id
It's useful to start listing the relations between the tables (objects) in plain English. For example:
A user belongs to an area code and an area code has many users.
An event happens in an area code and an area code has many events.
Both statements describe many-to-many relations, so you do need those two tables (sometimes called cross-reference tables).
Writing those statements always helps to understand the problem and ask questions about it. Assuming the statements above are correct, then having those two tables users_areas and events_areas is correct too. To build the select statement, note that there's only one column that both tables have in common: area_id (which by the way, would fit in a int, using bigint is a huge overkill, and I think the same goes for user_id and event_id). So area_id is the column you need to use to match them (the correct term is to join them).
Here's your select statement:
SELECT ea.event_id, ea.area_id, ua.user_id
FROM events_areas ea
INNER JOIN user_areas ua ON ea.area_id = ua.area_id
Or, assuming you also have an event table and a user table, which is likely the case, we expand the select to look like this:
SELECT e.name, u.name
FROM events_areas ea
INNER JOIN user_areas ua ON ea.area_id = ua.area_id
INNER JOIN users u ON u.user_id = ua.user_id
INNER JOIN events e ON e.event_id = ue.event_id
Okay I changed this based on your comment...
Create these tables:
Table: user
id
name
Table: user_area
id
user_id
area_id
Table: event
id
name
Table: event_area
id
event_id
area_id
Table: area
id
area_code
Then run this query:
SELECT event.name FROM event, event_area WHERE event.id = event_area.event_id AND event_area.area_id IN (SELECT area_id FROM user_area WHERE user_id = <CURRENTUSERSID>)
SELECT *
FROM users u
INNER JOIN users_areas ua
ON u.user_id = ua.user_id
INNER JOIN events_areas ea
ON ua.area_id = ea.area_id
INNER JOIN events e
ON ea.event_id = e.event_id