Php - about SQL-query with WRONG(?) database - php

Easy question for you but hard solution for me.=)
I have a database - USERS. In USERS I have two tables - USERS_INFO and EVENTS.
USERS_INFO contain next fields:
user_id
user_name
...
and
EVENTS contains next:
event_id
user_id
obj_id (this element means, for examle, when user_1 will change information
event about user_2 in this table appears record like:
event_id=1
user_id=user_1
obj_id=user_2)
So, as you can see, information about user_id, obj_1 from table EVENTS I get from table USERS_INFO in field user_id.
I connected it.
The question is = how to create right query?
I need to see something like this:
user_1 user_4 some_event_like_edit (means that user_1 changed smth in user_4)
I can create query, but it works wrong. I did -
SELECT USERS_INFO.user_name, EVENTS.event FROM USERS_INFO,EVENTS WHERE USERS_INFO.user_id=EVENT.user_id
BUt I cant create query for another field obj_id!!
Result give me the fields where EVENTS.user_id=EVENTS.obj_id
What I should do??

You just need to join to user table twice, like this:
SELECT u_1.user_name as Who_Changed,u_2.user_name as Who_Got_Changed, e.event
FROM EVENTS e
INNER JOIN USERS_INFO u_1
ON (u_1.user_id=e.user_id)
INNER JOIN USERS_INFO u_2
ON (u_2.user_id=e.obj_id)

Related

MySQL - How to get data from 3 tables

I seem to be a little stumped... I'm trying to get data from three tables, but they're not all inter-related -- one table relates to each of the other two.
Exams_taken
ID
exam_id
user_id
Exams_available
ID
exam_name
Users
ID
user_name
I want to create an output where I have the exam_id, exam_name, and user_name.
I thought I could figure out how to do this as a single query, but I'm lost. Is it possible? Or do I need to do a query on 'Exams_available' and then a loop with a second query to JOIN 'Exams_taken' and 'Users'?
Thanks,
Scott
If you need an output that contains exam_id, exam_name and user_name I can suppose that you need the Exams taken, so why not just query like this:
SELECT exam_id, E.exam_name, U.user_name FROM Exams_taken as ET
INNER JOIN Exams_available as E on ET.exam_id = E.exam_id
INNER JOIN Users as U on ET.user_id = U.user_id

Create a view table in MySQL but read data from 2 tables

I have 2 tables and need to make a View table
These are 2 tables that I have:
user table with some fields: id, username, email, pass
system_log table with 2 fields: uid, message (uid means user_id)
Now, I'd like to have a view table which gives me a table with 2 fields, username and message.
Here is my problem: I need username from user table in my view table while I have uid in my system_log table. Basically, instead of having uid, I need the username
The project and list of fields in the actual project are more than these but I just made it simple here to make my points clear.
You can use inner join to get the data from both tables
CREATE VIEW `view_name` AS
SELECT
u.user_name,
s.message
FROM users u
INNER JOIN system_log s ON u.id = s.user_id;
CREATE VIEW my_view AS
SELECT u.username, s.message FROM
user u INNER JOIN system_log s
ON u.id = s.user_id

Select all from table where another query retuns no results

I'm creating a register web application for someone and I want to make student search to add a student to the activities register slightly more accurate.
At the moment my prepared statement is:
("SELECT * FROM students WHERE first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern ORDER BY last_name ASC");
And that works great. I returns a list of all students that match the search query. However after doing that query, for each row that returns I want to check if the students.id and $_GET['activity'] do not appear in the participants table already.
$_GET['activity'] is an ID from activities.id
The final result I want is to display all students that are not already registered on that activity.
Is this possible in one query? As if it is I'd rather do that then have to run a query on each returns result to see whether it should be displayed or not.
I have looked into INNER JOIN as I've used it before, but I don't feel that is what I need. My main issue is how to run that query to check if each result is in the participants table already.
Hopefully that will make sense as I'm finding it hard to work out how to word it in my head.
My table structure:
students - id PRIMARY KEY AI, first_name (varchar255), last_name (varchar255), dob (date)
activities - id PRIMARY KEY AI, title (varchar255), description (varchar255)
participants - id PRIMARY KEY AI, student_id (INT), activity_id (INT)
EDIT Updating this to use the three tables in the question
If you want all students who do NOT have a certain activity, you use a query pattern like this. The LEFT JOIN retains all the records from the students table, and places NULL values in the columns from activities where the ON condition fails to match. You then throw in a WHERE condition to keep only those NULL values. Like so:
SELECT s.id, s.first_name, s.last_name
FROM students s
LEFT JOIN participants p ON s.id = p.student_id
LEFT JOIN activities a ON p.activity_id = a.activity_id AND a.activity LIKE :act
WHERE a.activity_id IS NULL
AND ( s.first_name LIKE :a OR s.last_name LIKE :b OR etc etc )
If your input is an activity_id, it's even easier.
SELECT s.id, s.first_name, s.last_name
FROM students s
LEFT JOIN participants p ON s.id = p.student_id AND p.activity_id = :act
WHERE p.activity_id IS NULL
AND ( s.first_name LIKE :a OR s.last_name LIKE :b OR etc etc )
As you've noticed, INNER JOIN can't do this, because it leaves out the rows from the first table that don't match the ON condition. But those rows are the very ones you want, hence the LEFT JOIN ... WHERE ... IS NULL.
Beware some things:
Don't use LIKE to match id values.
Don't use SELECT *. Instead, name the columns you want in your result set.
The sequence of OR ... LIKE clauses in your filter for the student table is not going to perform very well.
You could use a subquery to get the studentids that are registered for $_GET['activity'], and then remove them from the returned rows using NOT IN in your WHERE condition.
SELECT * FROM students
WHERE
(first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern)
AND
id NOT IN
(SELECT student_id FROM participants WHERE activity_id = :activity)
ORDER BY last_name ASC
where :activity is the placeholder for $_GET['activity']
try this query
"SELECT * FROM students WHERE first_name LIKE :pattern OR last_name LIKE :pattern OR id LIKE :pattern AND id NOT IN (select student_id From participants WHERE activity_id = activity)
Here 'activity' is $_GET['activity'] .

Joining 2 Tables and show the same column repeatedly based on its associative ID

Hi i am not sure how to put this in a brief sentences, but i have DB table like the following
User Table
user_id
username
and so on...
Item
item_id
item_name
Item_Equipped
equipped_id head (FK to item_id)
hand (FK to item_id)
user_id (FK to user_id IN User Table)
I would like to generate a query that will display like the following format
user_id | head | head_item_name | hand | hand_item_name | ...
So far i only able to do this:
SELECT user.user_id, user.username,
equipments.head, equipments.head_acc,
equipments.hand,
equipments.acc, equipments.body
FROM gw_member_equipped AS equipments
LEFT JOIN gw_member AS user ON user.memberid = equipments.member_id
Which (i have to be brutally honest) doesn't do anything much.
I tried to perform INNER JOIN between item and item_equipped however i am unable to get individual name for each item (based on its item ID)
you need to join ITEM table two times with ITEM_EQUIPPED table.
you can use below query for your desired output column shown in question..
SELECT USER.User_Id,
Item_Equipped.Head,
Item_Heads.Item_Id Head_Item_Id, -- if you want you can remove this column
Item_Heads.Item_Name Head_Item_Name,
Item_Equipped.Hand,
Item_Hands.Item_Id Hand_Item_Id, -- and this column also as these columns are same as their previous select columns
Item_Hands.Item_Name Hand_Item_Name
FROM USER, Item Item_Heads, Item Item_Hands, Item_Equipped
WHERE USER.User_Id = Item_Equipped.User_Id
AND Item_Heads.Item_Id = Item_Equipped.Head
AND Item_Hands.Item_Id = Item_Equipped.Hand

Calculate sum from two Tables for a specific User

i have an Table with Users and an Table with events that is related to the id from the Users Table. In each Event you can make points and i want to get the total points from an specific User.
It looks like this:
Users
+----+----------+
| id | username |
+----+----------+
Events
+----------+---------+--------+
| event_id | user_id | points |
+----------+---------+--------+
// The event_id is related to an Event Table with specific data about the Event. but that not relevant.
The best could be to get the data from the user and the total points that he got in one query.
Thanks and Greetings,
Mottenmann
"..to get the data from the user and the total points that he got in one query."
You need to join both tables first so you can manipulate the data. The query below uses INNER JOIN which only includes users on the result list if it has atleast one matching record on the Events. If you want to get all users even without a single matching record on the other table, use LEFT JOIN instead.
SELECT a.ID, a.username, SUM(b.points) totalPoints
FROM Users a
INNER JOIN Events b
ON a.ID = b.user_ID
GROUP BY a.ID, a.username
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
"In each Event you can make points and i want to get the total points
from a specific User."
You could do something like this:
select sum(e.points) as points from users u
left join events e ON (u.id = e.user_id)
WHERE u.id = {$id}
where {$id} is the id of user.

Categories