I need some help creating a query for my mySQL database. I have recently started using JOIN and IN to select rows from my database, so I apologize for sounding like a noob.
I am not looking for an answer (although one would be nice!) but advice on where I should start with my query would be greatly appreciated. Please do not just post a link to the PHP website or to a tutorial.
In my database, users are "linked", the order is NOT important.
Table Name: UserLinks
link_ID User_1 User_2
1 10982* 34982
2 82738 16643
3 10982* 99822
4 78256 10982*
The user that I am focusing on here is user 10982
1) The first part of this query that I would like to create find the ID of the users that this user (10982) is linked to. These users are user 34982, 99822, and 78256. I imagine it is something as simple as SELECT * FROM UserLinks WHERE User_1 OR User_2 = 10982, my issue here is, how do I obtain the values - given that I cannot simply choose a row to return (I considered using an if statement... if the value of User_1 is 10982, then choose User_2. This however, seems redundant.
With this list of Users ID's, I would like to run the second part of the query, to find which Event_ID's correspond to this list of users (the ID's of the users are now UserEv_ID):
Table Name: EventUserTags
ETag_ID UserEv_ID Event_ID
1 34982* 289
2 82738 231
3 99822* 990
4 78256* 486
2) The second part of this query will use the list generated from the first query (of user ID's) to generate a list of Event_ID's. I know that you can use the IN statement and just dump this list in to the query as an array, but that means making the results of the first part of the query into an array. This again, seems redundant. I would like to know how to properly select these Event_ID's using the User ID's... I think that the JOIN Query will work, but I need some advice on how to use this.
The values of Event_ID's obtained here are 289, 990, and 486. In last part of this query I need to use this list of Event_ID's generated from the last query to match up with the data of another table, my Events table.
Table Name: Events
Event_ID Event_Order
182 8728342
289 3478792*
990 1876623*
486 9617789**
3) Lastly, I need to use the Event_ID's obtained from the last query to obtain their corresponding Even_Order. Again, I know this can be done with the IN statement (using an array) but this will not be efficient at all.
The purpose of this query is to start with a single User's ID, and find the Event_Order of every user this user is linked to.
Any help is really appreciated
This can all be done fairly simply in one query which I will write and then explain:
SELECT
Event_Order, -- I think this is the one you need, but selecting other fields anyway
Event_ID,
User_1,
User_2
FROM
Events
NATURAL JOIN EventUserTags
JOIN UserLinks ON (
UserEv_ID = User_1 AND User_2 = 10982
OR UserEv_ID = User_2 AND User_1 = 10982
)
NATURAL JOIN is a short cut for JOIN EventUserTags ON (Events.Event_ID = EventUserTags.Event_ID). It works because the keys you are joining on have the same name.
Then you join on the respective user IDs only if the link has the user you're looking for.
Related
I'm trying to add a function to a script that orders a list of users and then allows that same order SQL to be used to create an export file. I'm writing it for a piece of software that hosts basic user data in one table, and the question value I'm trying to get in another. Here's the details:
Table1 is base_user and from it I need the values of columns id, username, and email. However, I want to add the option to order/export by users with all that same data, but by their sex.
Table2 is base_question_data and from it I want to get the question 'sex' value.
Users can pick between Male or Female (Values: 1 or 2), and that info is stored in a column named intValue. I've already tried using INNER JOINS and such selecting multiple info from both tables, but where I'm getting confused is how to say "Get id, username, email, and sex for every user that is X sex" where "X sex" is the gender the user set to order/export by. I'm having a hard time figuring out how to get the specifics for the sex value for each user, but also use it to only show all those users of that value. All ideas are appreciated.
EDIT:
Forgot to mention that in the 'base_question_data' table, column 'userId' is equal to column 'id' in 'base_user' table.
This is Table1 or base_user
This is Table2 or base_question_data
To clarify what I'm trying to do:
In the 'base_user' table, I want to select ID, Username, and Email. I have this working normally, as it's a simple query. I want to, however, let users order by each user's gender. So
1)They can order the preview list by Male (questionName = sex intValue = 1) or Female (questionName = sex intValue = 2). This way, it will show all user's ID, Username, and Email who are gender 1 or 2. Using this same query, I'm trying to let them export that data as well, so they can export only users of gender 1 or 2.
My problem is the process of combining all of this data. I need to combine base_user's "id" to base_question_data's "userId" and I need to also get the value of each user by targeting base_question_data's questionName='sex' and get the intValue based on if they're ordering by Male (value=1) or Female (value=2).
I've done LEFT JOINS when combining one value to another for two tables, and while this is still two tables, I've never done it where I need to combine two different keys from two tables while also ordering them all by two different column values in one of those tables.
I agree with #rowmoin but if you use LEFT JOIN it will give null value if no entry in your base_question_data table and if you use INNER JOIN it will ignore those records from both tables which does not match so you can not get users from base_user if you do not have related entries in base_question_data table.
The query was easier than I anticipated. I will explain it in detail here.
To achieve something like this, (in which I needed one table's two values to decide what I'm getting in my other table results), I simply changed the value of 'intValue' in my query, but you can also do this by assigning a php value to let it be dynamically changed if you want. Since I'm doing a change between 1 or 2, I just have to different queries with the respective variable.
Here's my query:
SELECT * FROM ow_base_user
INNER JOIN ow_base_question_data ON ow_base_user.id = ow_base_question_data.userId
WHERE questionName='sex' AND intValue='$value';
I finally realized this morning I needed to go backwards, rather, and select my conditionals from base_question, rather than from the base_user table. Using this query, (where $value=1 for male or $value=2 for Female) I have successfully gotten to return a list of user's who match the set $value with their IDs, Username, and Email.
So this is my sorta first time doing an Online RPG (MMORPG), It's a browser based-Pokemon game.
In the Database, l've created 2 tables;
1.Pokemons (Columns; ID#, PokemonName, PokemonType, Level, Exp, HPoints, ATT, DEF)
2.Users (Columns; ID, Full Name, E-Mail, Username, Password)
In the Register field, they put in their info (User, Pass, Email), then chooses a Starter Pokemon to fight with. My question is how would i interpret that into a SQL/PHP command that joins the starter pokemon to that User or vise versa?
Far as l know it's
SELECT * FROM table_name;
But let's say l wanted to choose THAT user who just registered. Would the * just automatically choose that player or will it select everything from the Users list (Currently 3 rows of users in the Table).
Im reading w3schools for the moment, but needed some real-time advice on how l should go about with this. Thanks again!
thepokemonrpg.x10.mx If you guys wanna see what l mean.
This would indeed select everything from the Users table:
SELECT * FROM Users
The * doesn't mean all records, it just means all columns for any matching record. However, since there's no filter, all records happen to be matching records. If you want to only select a single record from that table, you would add a WHERE clause:
SELECT * FROM Users WHERE Username='someusername'
There are a few different ways that you can construct the SQL query to include a value like that (since someusername would likely come from a variable and not be explicitly written like that). Just be aware of SQL injection vulnerabilities when building those queries. You wouldn't want to accidentally publish a website where users can write their own database code and execute it on your server.
As for joining the tables, I currently don't see a way that you could do that. These two tables define two distinct entities, but have no way to relate to one another. There are a couple of ways you could do that, depending on how these entities are actually related. To that end:
Does a Pokemon always have exactly 0 or 1 owner? or;
Does a Person always have exactly 0 or 1 Pokemon? or;
Can a Pokemon have many owners and a Person have many Pokemons?
If the first statement is true, then you can add a UserId column to your Pokemons table and make it a foreign key to the Users table. That way every Pokemon record would indicate which User owns it.
If the second statement is true, then you can add a PokemonId column to your Users table and make it a foreign key to the Pokemons table. That way every User record would indicate which Pokemon is currently owns.
If the third statement is true, then you'd need to add a joining table to maintain this many-to-many relationship. Something like this:
PokemonUsers
------------
Id
PokemonId
UserId
Every record in this table would essentially be a link between a record in the Users table and a record in the Pokemons table.
I am building a simple adress book website where you can enter information about a person and then enter information about adresses. You can then select where people lives using a drop down menu to update the building id attribute in the person to match the automaticly generated id in the building. What I can't figure out how to do print all info about all persons(this I can do) and then print the info about the building that matches each persons building id(this I have no idea how to do. Right now I am using a while loop to print each person. But I can't get the matching building to print.
Edit: also, thanks for all info I have gotten from this site in my learning of webbprograming
You could use joins in SQL to combine several tables in one query. Also you could use GROUP BY.
Just search for that and I think you will get a good tutorial in your language.
Here are some good links:
SQL JOIN, SQL GROUP BY
Could use some code and table names to help define this example a little better, but regardless, you need to change your mysql query. In your database you need at least 1 matching row between your persons table and your buildings table. This way you can JOIN them together using the common row.
I will be using id as a placeholder for the common row in this example. Somethings like this should work:
SELECT * FROM persons LEFT JOIN buildings ON(persons.id=buildings.id) WHERE persons.building_id = buildings.building_id
To get all the results from persons and buildings you will need a separate query. But, the query above should give you the results of the person's info where the building_id matches the building_id from buildings.
This is hopefully a quick php question...
I have stored a number of id's in a field on a user table like '1,2,3'. I now want to query another table against those numbers. I think my brain has gone to mush this morning because can't seem to get it right...
Could 'IN' be used in the query?
Update -
Realised I didn't explain my self well enough...
I have two tables, one for users (id, username, password, products) The 'products' field has comma separated id's in which related to another table which holds product information.
I am basically trying to filter out what a user can see, via a query to the database with that users privileges.
You should fix your database schema; then, querying will be obvious and efficient.
Every column in your database should contain atomic values. If you've stored multiple values in a single column, it means you should have created a table with a one-to-many relation.
CREATE TABLE user_whatever (user_id int, whatever_id int)
...with one row per item related to the user. To query another table against those numbers, you simply JOIN this new table in the query.
You may be better off using a join, hard to tell from your question what sort of data you're working with.
Join's would be far more efficient with large amounts of data.
without knowing your database structure it's impossible to help further
SELECT column_names
FROM table_one
INNER JOIN table_two
ON table_one.column_name=table_two.column_name
is the basic syntax.
You can use IN in SQL without any problem, but you will need to convert the PHP array to a compatible list for example using the implode(separator,array) function...
[Update] Seeing the question update: The technique you chose for saving the "products" is not very good and WILL cause you problems in the future. the standard solution for storing these values is creating an additional table (userid,productid) and the primary key is both fields in it you create multiple rows for each user/product permission.
To actually use the specific solution you created you will need to run an SQL getting the values from the table, and then using a SECOND SQL use the WHERE IN $ids to actually get the data (as far as I know you can not use the IN on a string result like this (no such thing as EVAL in SQL)
Like everybody said, you should use atomic values. But since everybody already explained that, I'm only going to clarify in detail what you should do.
Use a table for users, which contains the id, username and password, but without product
id - username - password
1 - mike - XXXX
2 - joe - XXXX
Then you have your products table
id - name - price
1 - Aluminum bat - 19.99
2 - Scattergun - 39.99
3 - BONK (with isotopes) - 14.99
Now, you introdouce a third table, which represents what users have bought.
user - product
1 - 2
1 - 3
2 - 1
Now, if you want to select the products that mike has bought, you just select all rows from the third table where the user id is equal to 1. In conjunction with foreign keys and indexes, the queries should also have a better performance. For clarification, this is how my example would look like in your current implementation.
id - username - password - products
1 - mike - XXXX - 2,3
2 - joe - XXXX - 1
$sql = "SELECT * FROM table
WHERE id IN (";
$i=1;
$count = count($array);
foreach($array as $a){
if($i==$count){
$sql .= $a['id'];
}else{
$sql .= $a['id'].','
}
$i++;
}
$sql .= ")";
Please try this..
Get the field with the ids ('1,2,3') from your first table into some variable -> $ids
$sql = sprintf(SELECT * FROM second_table WHERE id IN (%s),$ids);
Hope this helps.
ps.: I don't recommend storing id this way.
I need to store of 100-200 data in mysql, the data which would be separated by pipes..
any idea how to store it on mysql? should I use a single column or should I make many multiple columns? I don't know exactly how many data users will input.
I made a form, it halted at the part where multiple data needs to be stored.
Anyone know how to store multiple data in single column or is there any alternative way?
please help me..
thank you very much
You should implement your table with an ID for the source of the data. This ID will be used to group all those pieces of similar data so you don't need to know how many you have beforehand.
Your table columns and data could be set up like this:
sourceID data
-------- ----
1 100
1 200
1 300
2 100
3 100
3 200
When you query the database, you can just pull in all of the data with the same sourceID. With the data above, the following query would return two pieces of data.
SELECT data
FROM dataTable
WHERE sourceID = 3
If you have multiple tables, you'll need to associate them with each other using JOIN syntax. Say you have a main table with user data and you want to associate all of this input data with each user.
userID userName otherData
------ -------- ---------
1 Bob xyz
2 Jim abc
3 Sue lmnop
If you want to join data from this table (userTable) with data from the dataTable, use a query like this:
SELECT userID, userName, data, otherData
FROM userTable
LEFT JOIN dataTable
ON userTable.userID = dataTable.sourceID
WHERE userTable.userID = 1
This query will give you all of the data for the user with an ID of 1. This assumes that the sourceID in your data table is using the userID from the user table to keep track of who the extra data belongs to.
Note that this is not the only JOIN syntax in SQL. You can learn about other types of joins here.
Sounds like you need a join table. Have just the data you need in both tables, create a third table with the ID of both tables, then it doesn't matter if you need 100, 200, 300 or more.
If you have a form where this data is coming from, store each input from your form into it's own separate column.
Look for relationships in your data: sounds like you have a "has many" relationship which indicates you may want a linking table where you could do a simple join query...
Storing multiple data in a single column will be a nightmare for queries and updates, unless you're storing XML, event then it would give me nightmares...