In a case where I have a column that needs to be unique eg. product:eggs, tomatoes, pepper, pepper1, pepper2
and before i insert another pepper i need to check the last integer, and add 1 to it, so the next pepper would be 'pepper3'
How would i do this?
Thanks in advance
The easy way is to have two columns: the first for the label and the second for the id.
It's never good to mix up various information in the same column.
Then you could do something like :
SELECT MAX(product_id) FROM ... WHERE label = "pepper"
and
SELECT CONCAT(label,product_id) FROM ... WHERE id = ...
Returns what you want.
I would try something like this:
SELECT LEFT(product_name, 6) AS product_name_plain,
CAST(RIGHT(product_name, 6) AS UNSIGNED) AS product_number
FROM product_table
WHERE product_name_plain = "pepper"
ORDER BY product_number DESC
LIMIT 1
The SELECT breaks apart product names into the plain name ("pepper"), and an unsigned integer version of the product number (3).
The WHERE clause identifies the peppers.
The ORDER BY will sort them (which should result in the last pepper being the first result)
The LIMIT will only fetch the one result.
Note that "6" and "pepper" are hard-coded in this query, your code would have to put them in. 6 is the length of "pepper."
Related
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.
I have a MySQL chart table like this : PRIMARY KEY(ID), Name, Value, Date
I need to remove duplicates if "Name AND Value AND Date" are the same as existing row.
I have beneath a solution i found while ago and which worked (not 100%), but I don't understand the command in it's total because I'm only into BASIC MySQL... Can somebody explain me a little further...
definitely what is the x at the end ???
$delDups = "delete from chart where id not in (select * from (select min(id) from chart n group by value) x)";
mysql_query($delDups);
It appears to me that you could do it simpler, like this:
$delDups = "delete from chart where id not in (select min(id) from chart n group by value)";
In the subquery you are saing:
" Hey, take all the values and find the minimun id for the group of values"
So, imagine the result of the subquery as a list, like "(12, 13, 200)".. the NOT IN operator will take that list and use it to filter the result of the upper query and say "Give me all the results, less the ones where id is in this list"
I'm not sure if I explained it as expected...
You could add an unique key for all 3 columns:
ALTER IGNORE TABLE my_table
ADD CONSTRAINT uc_unic UNIQUE (Name, Value, Date)
As to that x,mysql permit aliases,essentially name shortcuts for convenience.
What you wrote will almost work, you just want to add the name and date to the GROUP BY clause. Something like this should do.
DELETE FROM chart
WHERE id NOT IN (
SELECT MIN(id)
FROM chart
GROUP BY name, value, date)
The DELETE FROM says you want to be deleting rows from a table. The WHERE clause says which rows you actually want to delete (missing it out will remove everything). The sub-query in the brackets will look through every combination of name, value and date and give you one id back from each combination. Putting it all together, the DELETE should now drop every row whose id isn't the smallest for each group.
Hope that helps!
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
for example i have a table like this :
name rating
matei 124
andrei 20
serj 25
john 190
mike 96
andy 245
tom 73
i need to output something like this(order by rating):
john's position is 2; or, tom's position is 5; (i don't need to get all result , just one )
How can I achieve this?
Thanks in advance
Generally order of rows in a query result is not guaranteed by MySQL unless ordering is explicitly specified with ORDER BY clause. If you have some separate ordering column, you may use query like the following:
SELECT count(1) as position
FROM table
WHERE order_column <= {john's order_column value};
If you don't have ordering column, I'd recommend you to define first, what does "john's position" and "tom's position" mean.
UPDATE:
AFAIU, you want to get position in list sorted by rating (sorry, I initially did not get it). So, rating would be your order_column. In this case, you should decide, how do you calculate position, if two guys have equal rating (who's position is higher?).
So, the query may look in the following way:
SELECT count(1) as position
FROM table
WHERE
rating > (SELECT rating FROM table WHERE id={user's ID});
SELECT COUNT(*) + 1
FROM users
WHERE (rating, name) <
(
SELECT rating, name
FROM users
WHERE name = 'john'
)
Note that if you will have duplicates on both name and rating, this query will assign the same rating to both of them.
Tables are more formally known as relations in database literature - they are not guaranteed to be ordered (they are sets of "tuples"), so your question doesn't make sense. If you need to rely on an order/position, you need to define an additional column (like an auto-incrementing ID column) to capture and store that info.
Is this any help > http://craftycodeblog.com/2010/09/13/rownum-simulation-with-mysql/ ?
Would offset not work like so?
SELECT * FROM Table ORDER BY rating DESC LIMIT 1,6
This would return 1 row that has been off setted by 6 rows ? or am I mistaken, the syntax would be
SELECT * FROM Table ORDER BY rating DESC LIMIT 1 , {{POS}}