Get X number of specific rows. Mysql query - php

Say I have a database with two tables: "food", and "whatToEat".
I query the "whatToEat" and find 3 rows:
id Food username
1 Apple John
2 Banana John
3 Milk Linda
If I want to get those from the "food" table, I can just do something like this i guess:
SELECT *
FROM food
WHERE username='John' AND typeOfFood = 'apple'
OR typeOfFood = 'Banana' OR typeOfFood = 'Milk'
... but is it possible to dynamically write this, since the "whatToEat" table will change all the time, or do I need a loop and query the "food" table one by one for each of the objects in "whatToEat"?
EDIT
The above is just an example, the real scenario is an online game. When it's a players turn in a game, he's put on the "matches_updated" table. This table just holds his name, and the id of the match (or matches since he can be in several at the same time). When a player recive an update, I would like to check if he have any matches that needs to be updated (query "matches_updated" table), and then pull the data and return to him from the "matches" table, where all the information is stored about the matches.
Example:
The player Tim query the "mathces_updated" table and find he have 2 new matches that needs to be updated:
match_id username
1 Tim
2 Tim
2 Lisa
1 John
3 John
... He now want to get the information about these matches, which is stored in the "matches" table:
match_id match_status player1Name Player1Score Player2Name Player2Score
1 1 John 123 Tim 12
2 1 Lisa 4 Tim 15
3 1 John 0 Lisa 0

I am not sure whether I understand the question correctly.
Actually It depends on the queried tables have what in common.
so if suppose food is a common column, then query something like this...
select * from food where food in (select food from whattoeat where username = ?)
Try it out, if it solves your problem...

SELECT * FROM matches_updated JOIN matches
ON matches_updated.match_id == matches.match_id
WHERE matches_updated.user == "Tim"
--
Perhaps you want a JOIN statement?
SELECT * FROM food JOIN whattoeat
ON food.username == whattoeat.username
WHERE food.username == "John"
I'm having a really hard time trying to understand what your desired result is - posting example of both tables in question, and the desired result of your query, might help.

SELECT * FROM food WHERE username='John'

Related

PHP queries - How to add new column and insert user info in table, when user id is stored in another table?

so I'm new to PHP, currently I'm making an PHP OOP authentification system. The login and registration works fine, but now I need to have an option for users to add unlimited attributes(input column name and value) to his profile, but the trick is that I need to store the attributes in another database table. So this is my users table.
uid upass fullname uemail
1 md5(pass) John Snow john#gmail.com
2 md5(pass) John Doe jdoe#gmail.com
And i think my new table should look something like this.
id uid age professsion gender
1 1 17 haha male
2 2 62 eee male
and so on. This system is just for educational purposes, it probably doesn't make any sense, that user can add unlimited attributes, but well it is what needs to be done. I'm hoping someone can help.
Thanks in advance.
EDIT
Ok i have made this function, but what do i have to echo out?
public function get_property($uid)
{
//$query = "SELECT property,value FROM info WHERE uid='$uid' AND property='Gender'";
$query = "SELECT uid, CONCAT('{', GROUP_CONCAT(property, ': ', value), '}') AS json FROM info GROUP BY uid";
$result = $this->db->query($query) or die($this->db->error);
$user_data = $result->fetch_array(MYSQLI_ASSOC);
echo $user_data['property'];
}
OH i guess it's json
I don't think that your proposed new table is a good choice, in particular because you mentioned that the user needs to be able to store unlimited attributes. Your suggested design places each attribute into a separate column, but this could become unwieldy as the number of attributes really starts to get large. Instead, I propose something like this:
uid | property | value
1 | age | 17
1 | profession | haha
1 | gender | male
2 | age | 62
2 | profession | eee
2 | gender | male
Now adding a new property just means inserting a record. Note that this table can easily be queried. If you wanted to find all male users you could do:
SELECT uid
FROM yourTable
WHERE
property = 'gender' AND value = 'male'
This design is flexible and we could index the property and value columns to improve performance.
Edit:
If you wanted to output each user's properties in a sort of JSONeqsue format, you could try using GROUP_CONCAT e.g.
SELECT
uid,
CONCAT('{', GROUP_CONCAT(property, ': ', value), '}') AS json
FROM yourTable
GROUP BY uid;
Output:
uid json
1 1 {age: 17,profession: haha,gender: male}
2 2 {age: 62,profession: eee,gender: male}
Demo
I would create another table, named "users_data", with two fields. One beeing the user id and the second beeing a BLOB, containing the fields of the user which he created. BLOBs are stored in serialized form, which you then can unserialize in PHP.
Doing it this way, you dont have to edit the database, rather then just adding data to the users data array or removing it.
You can select it by using something like this:
SELECT users.*, users_data.data FROM users JOIN users_data ON users_data.user_id = users.id
IMO this approach is even simpler to accomplish then doing it the way you described.
I think you can create a json object of user and map with id in other table and save json in one column against id. You can extract json easily and decode it properly.
If the User can input anynumber of dynamic attributes then you need to alter your table structure as below
user_tbl
uid upass fullname uemail
1 md5(pass) John Snow john#gmail.com
2 md5(pass) Adolf Hitler ahitler#gmail.com
user_attr_tbl [If any user inputs a new attr_name that's not existing in the table then you need to insert it to here.]
id attr_name
1 age
2 professsion
3 gender
user_attr_values
id uid user_attr_id value
1 1 1 17
2 1 2 haha
3 1 3 male
4 2 1 62
5 2 2 eee
6 2 3 male
You can create other table for storing additional user details with a table_name like 'user_attributes' or 'user_details' (or) your wish. Then You have to store 'user_id' while storing the additional data for user So that you can fetch all the additional user information by using Mysql JOIN's.
users
uid upass full_name uemail
1 md5('something') James Anderson jamesanderson#mail.com
2 md5('123456') Brett Lee brettlee#mail.com
Your user_details would be like below:
id uid age professsion gender
1 1 25 Faculty Male
2 2 26 Entreprenuer Male
You can fetch the data by using any one of Mysql JOIN's like below. Mysql Joins Reference joins
SELECT users.*,user_details.age,user_details.profession FROM users INNER JOIN user_details ON users.uid=user_details.uid

PHP/SQL: How to SELECT values from one table that do not exist in a completely different table

I have two tables, one with a list of projects and who is assigned to each project, and one with names and information about contractors.
"Projects_table"
Project_ID Contractor_assigned Job_Complete
1 Jim Smith 1
2 John Smith 0
3 Edward Smith 0
4 Smith Smith 1
5 Candle Stick 1
and
"Contractors_Table"
Contractor_ID Name Drywall Insulation
1 Jim Smith 1 0
2 John Smith 0 1
3 Edward Smith 0 1
4 Smith Smith 0 1
5 Jack BeNimble 0 1
6 Jack BeQuick 1 0
7 Candle Stick 0 1
What I need, is to pull an SQL query that gives me a list of the Contractors of a certain type (Drywall or Insulator) who are currently not assigned to any job, so long as that job is also not marked "Complete."
I've tried a few versions of this, but with no success:
SELECT
Name FROM Contractors_Table
WHERE Contractors_Table.Insulation=1
AND Name NOT IN
(SELECT Contractor_assigned FROM Projects_table WHERE `Job_Complete` = 0)
What I'm hoping for output from my above example is to get back:
Jack BeNimble
Candle Stick
Those two Insulators are not currently assigned a job, excluding the "complete" job.
Firstly your table design is wrong: you should store the Contractor_ID in the project table, and not their names (what happens with homonyms???)
Secondly I don't understand why your query doesnt return the expected result because it looks correct. Maybe because you have a column named Name, and this is a reserved keyword, and you should thus surround it with `
Anyway it's never efficient to do a NOT IN
You can rewrite that with an OUTER JOIN :
SELECT C.`Name`
FROM Contractors_Table C
LEFT JOIN Projects_table P ON C.`Name` = P.`Contractor_assigned` AND P.`Job_Complete` = 0
WHERE C.Insulation=1
AND P.ID IS NULL --> This will ensure that you only get those who are not in the Project table
You should use NOT EXISTS instead:
SELECT Name
FROM Contractors_Table c
WHERE c.Insulation = 1
AND NOT EXISTS
(SELECT 1
FROM Projects_table p
WHERE p.Job_Complete = 0
AND p.Contractor_assigned = c.Name)
You could refactor the query you are trying to do, but will take much more effort to use NOT IN.
You should also use foreign keys instead of names to compare data. You are duplicating information in relational database, which doesn't follow Normalization rules
Obviously a couple of queries (one for each type). If you use unique ID's in both tables for each of the contractors you can join the tables and select where Contractors_Table.drywall = 0 and Project_Table = 0 (Group by Contractor ID).
I think its just about getting your data sorted in your tables then writing the query.
HTH :-)

How do I also get the id of the last column I selected in my SQL Server query?

Example database of the table, employees:
id market firstName
1 1 John
2 2 James
3 1 Sally
4 1 Mary
5 2 Susan
If I write the following query,
SELECT firstName
FROM employees
WHERE market = 1
I will get the following array:
array("John", "Sally", "Mary")
I am using odbc to connect to a sql server and then odbc_fetch_array to retrieve the results. However, I wish to also have the id of the last firstName pulled, for example:
array("John", "Sally", "Mary", 4)
I already know how to do this with two queries, but I am wishing to improve performance, how would I do this in one query?
If it matters, I am using odbc to connect to a sql server.
Thanks.
Since you can't mix datatypes in an array, I'm going to assume it's ok with you if the last id is returned as a string.
In this case, you can use a UNION ALL:
SELECT firstName
FROM employees
WHERE market = 1
UNION ALL
SELECT CAST(MAX(id) AS varchar(31))
FROM employees
WHERE market = 1

Get the name with most repeated numbers value in table

I want to calculate how much some names repeated and to get he most repeated name out but cannot get it. I can calculate how much Michael has $fix in his rows. But I need who is the best of it in repeats.
SELECT COUNT(*) AS count FROM (SELECT * FROM names WHERE league='books' and $position='Michael' ORDER BY id LIMIT $limit) AS last12 WHERE $fix='1'
I want to print me Michael if he repeats the most:
Michael 1
Jack 1
Jack 1
Jack 1
Michael 1
Michael 1
Michael 1
Juni 1
Let's say you have a table called names with columns id, name, league, etc. You want to know how many Michael or Erick or whatever name are there. To do that, you need to group by that column and use count(*), like follows:
Select name, count(*) as count from names group by name
This will return the names with its respective counts.

How can I add up multiple columns in PHP and SQL with the same id?

I have two columns in a MySQL table, one called "Total Experience" and one called "id"
Is there a way to add up the value of Total Experience and put it in a variable for all users with the same id?
Example: There are 3 users: Steve, Jack, and Sam
Steve has the id of 1 and Total Experience of 500
Jack has the id of 1 and Total Experience of 400
Sam has the id of 2 and Total Experience of 700
Is there a way to select and add up Steve and Jack's Total Experience in a SQL query, as they have the same id?
Use GROUP BY to aggregate rows by a column.
SELECT id, SUM(`Total Experience`) AS experience
FROM YourTable
GROUP BY id

Categories