My current projects consist of Registration of families of different areas in a City. i want to Generate a Unique ID to each families in which i need this ID for another part of this project.Each area in the city have already a unique number eg: 855, 856, 857,etc
So my plan is to generate unique Family ID by combining unique number already have + text "FM"+ number (1,2,3....) and store this uid to DB along with family details.
For eg (Area-855): 855FM1, 855FM2, 855FM3....
if the last registered family uid is 855FM40 , then next family uid must be 855FM41. so i want to fetch the largest value from uid field. in above eg:, largest is 855FM41. how i do this. ?
i have simple logic that fetch all uid, then split it after "FM". then find largest ,etc
How i solve this problem.? is there any simple way other than this.?
Using ORDER command you can sort your data by ordering of one column ascending or descending.
so first we order FamilyID column descending (in sql we use DESC) and then we get the first row which has biggest FamilyID value using "LIMIT 0,1" command
Try this:
SELECT * FROM families ORDER BY FamilyID DESC LIMIT 0, 1
You should use two columns instead of one. For example this:
FamilyID
--------
855FM1
855FM2
Should be stored as:
CityID FMNumber
------ --------
855 1
855 2
This way the data should be easier to manage and less redundant. And yes, it is possible to define primary or unique keys over multiple columns.
Related
I am writing a complex MySQL query. My actual query is more complex than I mentioned below.
I have a table named example and columns are id, name, option_1, option_2 . Of course id column is PK . I want to retrieve like this:
SELECT `id`,`name`,count(`option_1`),count(`option_2`)
My problem is I want to use "GROUP BY `id`" for count(`option_1`) and "GROUP BY `name`" for count(`option_2`) respectively. Now I have to break down it into multiple code in my php code.
How can I achieve what I want in a single query?
What you're asking for doesn't make a ton of sense. You want option 1 grouped by id and option 2 grouped by name, and you want to show all four columns in one result set.
First of all, if id is a primary key, then the count will just be the number of rows in the table since there will be no duplicate ids.
Second, even if id wasn't a primary key, and there were duplicate values, the grouping is different, so the counts represented in your result set would be grouped incorrectly.
Given that id is a primary key, perhaps your intention is actually to get a total count of the rows in the table. Perhaps this query would suit your needs?
SELECT
name,
COUNT(option_2) AS options
FROM
example
GROUP BY
name
UNION ALL
SELECT
'Total' AS name,
COUNT(*) AS options
FROM
example
This should get you a count of all the option_2 values, grouped by name, with the final row having a name of 'Total' and the count being the total number of rows in the table.
Aside from that, I'm not sure you're going to find the answer you're looking for due to the problems you would encounter matching up groupings.
I would like to know how to update my database table with new data but having the latest data be at the top with the unique id starting at 1. Here's what I mean:
First insert query, for example, inserts 3 article topics:
id article
1 firstNews
2 secondNews
3 thirdNews
Then the next time I run a Cron job to check for new articles, for example two new articles appear, I want the two new articles to be in the beginning of the table, like this:
id article
1 NewArticle1
2 NewArticle2
3 firstNews
4 secondNews
5 thirdNews
Hope that made sense. This might be a bad way to do it, I guess I could have a column with insert date() and then get the data out OrderBy date but it has to be an easier way to do this. I think this would be the easiest to output the most recent data from the table...
If I do ORDER BY DESC, it would output NewArticle2 before NewArticle1, which would defeat the purpose...
id article
1 firstNews
2 secondNews
3 thirdNews
4 NewArticle1
5 NewArticle2
So by DESC, id 5 would be the first one output...I was really hoping there was a way around this...
You should never do this. Just insert at the end, and to get the latest articles, use a query:
SELECT * FROM articles ORDER BY id DESC;
In general: Don't fit the data to your query, fit the query to your data. The id is not a position or number, it uniquely identifies that row of data.
You could use a Date columns and sort on that. Or just sort by ID descending.
It's rarely a good idea to change a PK in place. Not least, you mah have child tables using that PK and maybe history tables too
Note that there is no implicit order to a SQL table: you always need an ORDER BY to guarantee the resultset order
You should add another column specifically for sorting, e.g. a date. and add an INDEX on it.
Then the query becomes:
SELECT *
FROM news
ORDER BY newsdate DESC
Latest news comes first
If there are two news items that could be posted at exactly the same time, you may wish to include a secondary sort:
ORDER BY newsdate DESC, id ASC
It shouldn't be your concern at all.
ID is not a number nor a position by any means. It's just an unique identifier.
Means every database row sticks to it's id forever. While you want to assign your "unique" id to the every newcoming news, which makes no sense.
So, just have usual autoincremented id and select it using ORDER BY id DESC to have latest entries first.
I have a table that stores data that has been entered regarding the amount of waste put in a bin. So my table looks like this:
Material | Weight
===================
Paper | 10
Plastic | 5
Paper | 7
As you can see, I'm going to have duplicate data in the table. At the moment I have multiple instances of different materials, and they all have different weight values attached to them.
Is it possible in PHP to get these duplicate entries, combine them in to one entry, and then display them? So the code would take the 10Kg of Paper and add it to the other instance of paper in the table (7Kg) and then output the value?
I have tried the GROUP BY in MySQL, but all that will do is combine all of the entries and give me the value of the top record, which isn't right.
Thanks!
Use MySql, with a SUM column. This will sum up all values for that column, for each grouping. This is assuming the weight column is just a number (10 instead of 10kg).
SELECT
`material`,
SUM(`weight`) AS `weight`
FROM `material_weights`
GROUP BY `material`
If the weight column isn't just a number (10kg instead of 10), then there will be issues.
If all weights are in KG, then you should just remove the 'kg' value from each weight, and convert the weight column from text into a numeric column.
If there are different kinds of weights (KG, LB, G, etc), then the best way would be to have an extra field in the table, with the weight converted into KG.
Since all your data seems to be in strings, it seems like you would be best served by using a php migration script to examine your data and then combine duplicates. First thing you want to do is determine which Materials have duplicates.
SELECT Material FROM {TABLE} GROUP BY Material HAVING COUNT(*) > 1;
From there you should loop through the materials that come back, and grab all rows with the Material value.
SELECT * FROM {TABLE} WHERE Material = '{$material}';
This will give you all the rows labeled that Material. From there, apply any transformations (just in case there are values labeled g, for example) to the numeric value to ensure you're operating on the same type of value. Then you'd delete all the rows with that type of material. (You have a backup, right?)
DELETE FROM {TABLE} WHERE Material = '{$material}';
Lastly, insert the value you just determined.
INSERT INTO {TABLE} (Material, Weight), ('$material', '$weight');
SELECT
material,
SUM(CAST(REPLACE(weight, 'kg', '') AS UNSIGNED)) AS weightsum
FROM
tbl
GROUP BY
material
You can use the SUM() function with GROUP BY to get the sum of the weight per unique material. In your case, your weight field appears to be a string. You can simply take out the 'kg' from each value using REPLACE, then convert it to an integer, which is then passed to SUM().
I have a table with three fields - userID, couponID, last_couponID.
When the user accesses a coupon, I run this query:
mysql_query("INSERT INTO users_coupons (userID, couponID) VALUES ('$recordUserID', '$recordCoupID')");
Further, I have another query that should insert the last couponID into the field last_couponID, by polling the database table and finding the most recent result for the current userID.
I believe it is as such:
SELECT couponID FROM users_coupons ORDER BY userID LIMIT 1
Am I correct? Or should I use a different query?
Like this:
userID couponID
1 3
1 13
1 23
2 5
2 3
So if I wanted userID 2's latest coupon, it'd be '3', and for userID 1, it'd be '23'. I just want the last entry in the database table where the userID matches a value I provide.
I would just add a primary key (autoincrementing) to the users_coupons table.
When you want the latest coupon of a user,SELECT couponID FROM users_coupons WHERE userID = ? ORDER BY id DESC LIMIT 1
Assuming that couponID is numeric, and the last couponID for a certain userId is the greatest (as a number), you can do:
SELECT MAX(couponID) AS lastCouponId FROM users_coupons WHERE userId = <put here the user id>
EDIT: since you've edited your question, I edit my answer.
You have to add an auto-increment primary key, otherwise you can't know exactly which entry is the last one. When I answered, I supposed the last coupon for a certain userId was the one with the greatest couponId. Are you sure you can't just make things work this way?
Something along the lines of...
SELECT couponID
FROM users_coupons
WHERE userID = <current user id>
ORDER BY <primary key of user_coupons table if it's an identity column> DESC
LIMIT 1
...is more appropriate. Your query as it stands doesn't do anything with the 'current' user ID.
If you are actually after the highest couponID then SELECT MAX(couponID)... as suggested by Giacomo is a good idea - coupled with a check for the UserID matching the current user ID.
#Giacomo's answer is valid if you are incrementing the CouponID reliably as an identifier. If you have merged in data or are adjusting this value any other way then it may not be correct.
In theory, if you consider CouponID to be a surrogate key then you cannot use it to explicitly determine insert order. If you intend for it to be used for the purpose of insert order then you also need to make sure your supporting code and DB maintenance plans promote this use.
I contend that the "correct" method is to also store a DateTime
I have got table with 300 000 rows. There is specially dedicated field (called order_number) in this table to story the number, which is later used to present the data from this table ordered by order_number field. What is the best and easy way to assign the random number/hash for each of the records in order to select the records ordered by this numbers? The number of rows in the table is not stable and may grow to 1 000 000, so the rand method should take it into the account.
Look at this tutorial on selecting random rows from a table.
If you don't want to use MySQL's built in RAND() function you could use something like this:
select max(id) from table;
$random_number = ...
select * from table where id > $random_number;
That should be a lot quicker.
UPDATE table SET order_number = sha2(id)
or
UPDATE table SET order_number = RAND(id)
sha2() is more random than RAND().
I know you've got enough answers but I would tell you how we did it in our company.
The first approach we use is with additional column for storing random number generated for each record/row. We have INDEX on this column, allowing us to order records by it.
id, name , ordering
1 , zlovic , 14
2 , silvas , 8
3 , jouzel , 59
SELECT * FROM table ORDER BY ordering ASC/DESC
POS: you have index and ordering is very fast
CONS: you will depend on new records to keep the randomization of the records
Second approach we have used is what Karl Roos gave an his answer. We retrieve the number of records in our database and using the > (greater) and some math we retrieve rows randomized. We are working with binary ids thus we need to keep autoincrement column to avoid random writings in InnoDB, sometimes we perform two or more queries to retrieve all of the data, keeping it randomized enough. (If you need 30 random items from 1,000,000 records you can run 3 simple SELECTs each for 10 items with different offset)
Hope this helps you. :)