Hopefully this is a quick and easy question to answer.
I have a MySQL Database with the following fields:
shoe_size and waist_size
The shoe_size entries range anywhere from 3 to 21 (incrementing by halves-- 3, 3.5, 4, 4.5, etc).
The same is true for the waist_size entries.
My question is this:
Using PHP, how can I best consolidate this into a table that counts the total number of sizes, so that it could essentially be used as an Order Form?
For example, the MySQL table looks like this:
----------------------------------------------
| Name | shoe_size | waist_size |
----------------------------------------------
| John | 9.5 | 33 |
----------------------------------------------
| Steve | 9 | 32 |
----------------------------------------------
| Tom | 9.5 | 33 |
----------------------------------------------
| Sally | 7 | 8 |
----------------------------------------------
| Jane | 7 | 8 |
----------------------------------------------
And the output HTML (table?) would look something like this:
ORDER FORM
------------------------------------------
| Shoe Size | 7 | 9 | 9.5 |
------------------------------------------
| Total Pairs | 2 | 1 | 2 | <----- This is calculated from above
------------------------------------------
------------------------------------------
| Waist Size | 8 | 32 | 33 |
------------------------------------------
| Total Pairs | 2 | 1 | 2 | <----- This is calculated from above
------------------------------------------
I'm not even sure if my format for the "Order Form" table is the best way to go on this. Any nudge in the right direction would be greatly appreciated.
MySQL might be enough for this task, try something like
SELECT shoe_size, COUNT(id) as count FROM table GROUP BY shoe_size ORDER BY shoe_size asc
I think what you are looking for is GROUP BY.
(http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html)
e.g:
SELECT `Shoe Size`, COUNT(*) FROM table_name GROUP BY `Shoe Size`
Related
Hello :) I am fairly new to using INNER JOIN and still trying to comprehend it's logic which I think I am sort of beginning to understand. After being across a few different articles on the topic I have generated a query for finding duplicates in my table of phone numbers.
My table structure is as such:
+---------+-------+
| PhoneID | Phone |
+---------+-------+
Very simple. I created this query:
SELECT A.PhoneID, B.PhoneID FROM T_Phone A
INNER JOIN T_Phone B
ON A.Phone = B.Phone AND A.PhoneID < B.PhoneID
Which returns the ID of a phone that matches another one. I don't know how to word that properly so here is an example output:
+---------+---------+
| PhoneID | PhoneID |
+---------+---------+
| 17919 | 17969 |
| 17919 | 22206 |
| 17919 | 23837 |
| 17920 | 17970 |
| 17920 | 22203 |
| 17920 | 23834 |
| 17921 | 17971 |
| 17921 | 22225 |
| 17921 | 22465 |
| 17921 | 24011 |
| 17921 | 24047 |
| 17922 | 17972 |
| 17922 | 22198 |
| 17922 | 23879 |
| 17923 | 17973 |
| 17923 | 22199 |
| 17923 | 23880 |
+---------+---------+
You can note that on the left there is repeating IDs, the phone number that matches will be on the right (These are just the IDs of said numbers). what I am trying to accomplish, is to actually change a join table relative to the ID on the right. The join table structure is as such:
+----------+-----------+
| T_JoinID | T_PhoneID |
+----------+-----------+
Where T_JoinID is a larger object with a collection of those T_PhoneIDs, hence the join table. What I want to do is take a row from the original match query, and find the right side PhoneID in the join table, then update that item in the Join to be equal to the left side PhoneID. Repeating this for each row.
It's sort of a way to save space and get rid of matching numbers, I can just point the matching ones to the original and use that as a reference when I need to retrieve it.
After that I need to actually delete the original numbers that I reset the reference for but... This seems like a job for 2 or 3 different queries.
EDIT:
Sorry I know I didn't include enough detail. Here is some additional info:
My exact table structure is not the same as here but I am only using the columns that I listed so I didn't consider the fact that any of the others would matter. Most of the tables have a unique ID that is auto incremented. The phone table has carrier, type, ect columns. The additional columns I felt were irrelevant to include, but if there is a solution that includes the auto incremented ID of each table, let me know :) Anyway, I sort of found a solution, using multiple queries though I am still interested to learn and apply knowledge based on this question. So I have a that join table that I mentioned. It might look something like this for the expected results. There is a before and after table in one sorry for poor formatting.
+--------------------+---------+----------+---------+
| Join Table Results | | | |
+--------------------+---------+----------+---------+
| Before | | After | |
| Join | Table | Join | Table |
| PersonID | PhoneID | PersonID | PhoneID |
| 1 | 1 | 1 | 1 |
| 1 | 2 | 1 | 2 |
| 1 | 3 | 1 | 3 |
| 2 | 4 | 2 | 1 |
| 2 | 5 | 2 | 5 |
| 2 | 6 | 2 | 6 |
| 3 | 7 | 3 | 5 |
| 3 | 8 | 3 | 5 |
| 3 | 9 | 3 | 5 |
| 3 | 10 | 3 | 8 |
| 3 | 11 | 3 | 9 |
+--------------------+---------+----------+---------+
So you can see that in the before columns, 7, 8, and 9 would all be duplicate phone numbers in the PhoneID - PhoneID relationship table I posted originally. After the query I wanted to retrieve the duplicates using the PhoneID - PhoneID comparison and take the ones that match, to change the join table in a way that I have shown directly above. So 7, 8, 9 all turn to 5. Because 5 is the original number, and 7, 8, 9 coincidentally were duplicates of 5. So I am basically pointing all of them to 5, and then deleting what would have been 7, 8, 9 in my Phone table since they all have a new relationship to 5. Is this making sense? xD It sounds outrageous typing it out.
End Edit
How can I improve my query to accomplish this task? Is it possible using an UPDATE statement? I was also considering just looping through this output and updating each row individually but I had a hope to just use a single query to save time and code. Typing it out makes me feel a tad obnoxious but I had hope there was a solution out there!
Thank you to anyone in advance for taking your time to help me out :) I really appreciate it. If it sounds outlandish, let me know I will just use multiple queries.
FYI, I am using PHP and MySQL.
I am working on converting our spreadsheet staff rota to a more interactive online rota system.
I can get all the functions of the rota system fine, but when it comes to formatting it to make it clear of the departments and roles within each department, it is not so obvious.
I dont want to have to create a call to the database for each department and each role within the departments, but am stumped as to how to it to group the results and then output the results correctly and with the formatting I would like.
I do understand that this may be a very vague explanation of what I am trying to get to happen, and feel free to ask as many questions as you like.
I hope I make sense :-)
Have a great day
MySQL Data
ID | Name | Dept | Role
---|--------|------|------
1 | John | 1 | 2
2 | Steve | 1 | 2
3 | Colin | 1 | 3
4 | Trevor | 1 | 3
5 | Nigel | 2 | 4
6 | Gary | 2 | 5
Desire page/table format
STAFF | ..
-------|---
John | ..
Steve | ..
-------|---
Colin | ..
Trevor | ..
-------|---
TOT D1 | ..
-------|---
Nigel | ..
-------|---
Gary | ..
-------|---
TOT D2 | ..
If you want to get the values for each employee and the sum by department you can use the WITH ROLLUP modifier of the GROUP BY clause with adds extra rows with the totals by each value of the grouped columns.
Supposing that you want to show the salary:
select coalesce(name,concat('Total D',Dept)) as Name, sum(Salary) as Salary
from Staff
group by Dept, name with rollup
having coalesce(Dept,0)!=0
Results:
| Name | Salary |
|----------|--------|
| Colin | 80000 |
| John | 100000 |
| Steve | 120000 |
| Trevor | 40000 |
| Total D1 | 340000 |
| Gary | 60000 |
| Nigel | 50000 |
| Total D2 | 110000 |
The HAVING condition if for excluding the final row with the grand total, if you want that row you have to change a bit the COALESCE() to get the proper description:
select coalesce(name,concat('Total D',Dept),'Grand total') as Name, sum(Salary) as Salary
from Staff
group by Dept, name with rollup
Results:
| Name | Salary |
|-------------|--------|
| Colin | 80000 |
| John | 100000 |
| Steve | 120000 |
| Trevor | 40000 |
| Total D1 | 340000 |
| Gary | 60000 |
| Nigel | 50000 |
| Total D2 | 110000 |
| Grand total | 450000 |
i'm new to MySQL and PHP. And i have some problems trying to get data values from two tables in one query using JOIN. What i want to do is query "user_builds" and SUM(amount) where the owner_id=1 AND type=1. The problems comes in now where i have to grab the build_type from another table called "builds".
I have tried to solve this as i mentioned with JOIN, but the closest i came was to get the amount of rows that was equal to how many rows user_id=1 had.
What i want is select the total SUM of "amount"(user_builds) where "type=1"(builds) and "owner_id=1"(user_builds).
I hope you understand what i try to do here, if not i will try to elaborate it more. And also sorry for not providing any of the querys i tried, but as none of them worked it feels irrelevant. Thank you for your time.
Edit:
+-------------------+
| user_builds |
+---------+---------+----------+-------+
| id |owner_id | build_id | amount|
+---------+---------+----------+-------+
| 1 | 1 | 1 | 5 |
| 2 | 2 | 2 | 15 |
| 3 | 2 | 3 | 15 |
| 4 | 1 | 4 | 5 |
| 5 | 1 | 5 | 5 |
| 6 | 1 | 6 | 10 |
+---------+---------+----------+-------+
+----------------------+
| build |
+---------+------------+-----------+--------+
| id | name |description| type |
+---------+------------+-----------+--------+
| 1 | House | desc | 1 |
| 2 | Kitchen | desc | 2 |
+---------+------------+-----------+--------+
I want to query "user_builds" and get the total of "amount" where owner_id=1 and type=1. (type is found in "build" table).
Try this code, I hope it works appropriately.
select sum(ub.amount)
from user_builds ub
left join build b
on ub.build_id = b.id
where b.type=1
and ub.owner_id = 1
select SUM(amount) from user_builds left join builds on build.type = user_builds.type where "owner_id=1"
try this query and replace my query field with your original fields
best of luck...
Okay, so lets say that we have 4 columns and 3 rows of data.
|user_id|pick_1|pick_2|pick_3|
-------------------------------
|fred |C++ |java | php |
------------------------------
|eric |java |C++ | php |
------------------------------
|sam | C++ | php | java |
------------------------------
So right now, users are entering their favorite languages. The first pick(pick_1) would be the favorite programming language and the second pick (pick_2) would be the 2nd favorite programming language and etc.
How can I organize this in a way so that I can give a point value according to what columns the programming languages are. So maybe pick_1 can give 3 points, pick_2 can give 2 points and pick_3 can give 1 point.
So when you tally up the scores, C++ will have 8 points, java will have 6 points, and php will have 4 points.
That way I can give an overall ranking of what tends to be the more favorable programming language. Like so
|rank|language|points|
----------------------
| 1 | C++ | 8 |
----------------------
| 2 | java | 6 |
----------------------
| 3 | php | 4 |
----------------------
It doesn't even need to have a point system, I just couldn't think of another way to rank the languages on a scale of liked to un-liked. So if there's another way to yield the same results than please let me know. Otherwise how would I be able to do this. Preferably in just MySql. I am currently using PHP.
Thank you for reading.
You need a simpler structure
User_ID | Pick | Points
Fred c++ 3
Fred php 2
Fred java 1
This way you can do a simple sum(points) group by pick
for a SQL only solution, I would normalize your structure, and put the picks in a different table:
users: user_id; user_name
picks: pick_id; user_id; language; points;
then you would have your data in 2 tables:
| user_id | user_name |
-----------------------
| 1 | Fred |
-----------------------
| 2 | Eric |
-----------------------
| 3 | Sam |
-----------------------
| pick_id | user_id | language | points |
---------------------------------------------
| 1 | 1 | C++ | 1 |
---------------------------------------------
| 2 | 1 | Java | 2 |
---------------------------------------------
| 3 | 1 | php | 3 |
---------------------------------------------
| 4 | 2 | Java | 1 |
---------------------------------------------
| 5 | 2 | C++ | 2 |
---------------------------------------------
| 6 | 2 | php | 3 |
---------------------------------------------
| 7 | 3 | C++ | 1 |
---------------------------------------------
| 8 | 3 | Java | 2 |
---------------------------------------------
| 9 | 3 | php | 3 |
---------------------------------------------
And then use the following query to fetch the desired result:
SELECT language, SUM(points) FROM users JOIN picks ON users.user_id=picks.user_id GROUP BY language
As seen in this fiddle
This way it's also easy to add constraints so people can not vote for a language more then once, or give the same amount of votes to 2 different languages.
i have a table in following format:
id | title
---+----------------------------
1 | php jobs, usa
3 | usa, php, jobs
4 | ca, mysql developer
5 | developer
i want to get the most popular keywords in title field, please guide.
If you have a list of keywords, you can do the following:
select kw.keyword, count(*)
from t cross join
keywords kw
on concat(', ', t.title, ',') like concat(', ', kw.keyword, ',')
As others have mentioned, though, you have a non-relational database design. The keywords in the title should be stored in separate rows, rather than as a comma separated list.
If your data is small (a few hundred thousand rows or less), you can put it into Excel, use the text-to-columns function, rearrange the keywords, and create a new, better table in the database.
SELECT title 1, COUNT(*) FROM table GROUP BY title 1
EDIT
Since you've edited and presented a non-normalized table, I would recommend you normalize it.
Have a read of: http://blog.fedecarg.com/2009/02/22/mysql-split-string-function/
You need to modify your database. You should have something like this:
items
+----+---------------+
| id | title |
+----+---------------+
| 1 | something |
| 3 | another thing |
| 4 | yet another |
| 5 | one last one |
+----+---------------+
keywords
+----+-----------------+
| id | keyword |
+----+-----------------+
| 1 | php jobs |
| 2 | usa |
| 3 | php |
| 4 | jobs |
| 5 | ca |
| 6 | mysql developer |
| 7 | developer |
+----+-----------------+
items_to_keywords
+---------+------------+
| item_id | keyword_id |
+---------+------------+
| 1 | 1 |
| 1 | 2 |
| 3 | 2 |
| 3 | 3 |
| 3 | 4 |
| 4 | 5 |
| 4 | 6 |
| 5 | 7 |
+---------+------------+
Do you see the advantage? The ability to make relations is what you should be leveraging here.