How to make two updates in one query in MySQL? - mysql

Having a table like this one:
+----+-------+
| id | Value |
+----+-------+
| 1 | 1000 |
| 2 | 1500 |
| 3 | 1250 |
| 4 | 2000 |
| 5 | 1800 |
+----+-------+
How can I update the column "value" while adding, for exame, x% for those who are less than 1600 and y % for those greater than this value in one query? Is it possible?
I can't update the lowest first because eventually some value may exceed the range of 1600. That way, when I have updated the largest , could do it in values that had already received the increase .

You can use a case statement:
update table t
set value = value * (case when value < 1600 then 1 + x
when value > 1600 the 1 + y
else 1
end);

Related

SQL query to find set of doc_ids where there is maximum intersection of ent_ids

I have a table with O(1M) rows with columns doc_id and ent_id where (doc_id, ent_id) is the primary key.
+--------+--------+
| doc_id | ent_id |
+--------+--------+
| 1 | a |
| 1 | b |
| 1 | x |
| 1 | y |
| 2 | a |
| 3 | a |
| 3 | x |
| 3 | y |
| 4 | x |
| 4 | y |
+--------+--------+
My question is, How do I efficiently find a set of doc_ids ( say I need top 1000 or 5000 doc_ids) where there is maximum intersection of ent_ids among that selected set of doc_ids?
For example : In the above table,
say I need top 2 doc_ids where there is maximum intersection among their ent_ids.The result would be - doc_ids = {1,3} with [ common ent_ids={a,x,y}, common ent_ids count=3 ]
say I need top 3 doc_ids where there is maximum intersection among their ent_ids. The result would be - doc_ids = {1,3,4} with [ common ent_ids={x,y}, common ent_ids count=2 ]
footnote - If it's not possible do it efficiently with SQL, any direction towards alternative method of doing it in application code would also be helpful. say, convert to csv -> some data-structure[inverted index?]/library + python code -> result set.

How to find max of mysql varchar column

i have a table like this with a var char field reference_number
actually i need to get the max of number in that field
<<student>>
|`id` | `reference_number`(varchar(25))
--------------------------
| 1 | L250
| 2 | SP521
| 3 | S120
| 4 | SP500
| 5 | S122
the desired result is 521 because if we are avoiding the non numeric value then it will come like this
|`id` | `reference_number`
--------------------------
| 1 | 250
| 2 | 521
| 3 | 120
| 4 | 500
| 5 | 122
how to get the the value 521 from the table
I assume you have extracted 'reference_number' as shown in the second snippet from the first snippet. if so, try :::
select max(cast (reference_number as int)) from student
In order to get the number 521 (and all the numbers from the reference_number column) you could try:
SELECT *
FROM yourtable
WHERE reference_number REGEXP '^[0-9]+$';
And then you can add an order by statement.

Mysql concatenate only specific rows

In Mysql, I have the following table:
id | paramname | paramcategory | value |
---+-------------+-------------------+-----------------+
1 | width | dimensions | 240 |
2 | height | dimensions | 400 |
3 | param1 | category1 | some value 1 |
4 | param2 | category1 | some value 2 |
5 | param3 | category10 | some value 100 |
...
I'd like to have a query that will return a table with only several rows concatenated, and all other rows should remain intact, something like this:
paramname | value |
--------------+--------------+
width, height | 240 x 400 |
param1 | some value 1 |
...
I'm thinking about concatenating based on the needed paramcategory, but if possible/needed, concatenation can happen for specific paramnames as well. Whatever is easier/simpler.
Any help please?
Looking at this problem from above, you are going to have to 'UNION' 2 queries together. The first part of the union is your concat'd results, the second your original rows. For the first part you are going to need to do a self join on this table, along the lines of
select concat(a.paramname, b.paramname), concat(a.value, b.value) from table a, table b where a.paramcategory = b.paramcategory
along those lines....
Actually if you swap the 2 parts of the union around, you'll keep the original column names too.

Flag the row with the max value in field B based on name field in Field A

I am able to find the row with the maximum value for a Value field in an given set of records with the same name using
Select Name, Max(Value) from table group by Name, Value
which returns to me the record with the highest value but I am looking to turn this into an update so I can
Flag the record with the highest value in a IsMaxValue
For each record in the Name, Value group store the highest value found in a 'MaxValue' field
Simple select version is here:
http://sqlfiddle.com/#!9/ccd32/5
with fields ready for updates as per above if it is possible.
I believe this statement is what you might be looking for:
update maxvalues
join (
Select Color, Max(`Value`) max_value
from MaxValues
group by Color
) a on maxvalues.color = a.color and value = a.max_value
set ismaxrecord = '1', maxrecordid = a.max_value;
Sample SQL Fiddle
Given your sample data the table would look like below after the update:
| Color | Value | IsMaxRecord | MaxRecordID |
|--------|-------|-------------|-------------|
| Orange | 1 | | 0 |
| Orange | 2 | | 0 |
| Orange | 3 | 1 | 3 |
| Black | 30 | 1 | 30 |
| Black | 20 | | 0 |
| Black | 10 | | 0 |

Using MIN() in SET statement MySQL

I am using MySQL. Lets call a table that I have as Inventory which looks is below:
+----+--------+--------+-------------+----------+
| ID | Price1 | Price2 | TargetPrice | Quantity |
+----+--------+--------+-------------+----------+
| 1 | 12 | 1 | | 0 |
| 2 | 3 | 3 | 3 | 2 |
| 3 | | 4 | | 0 |
| 4 | 2 | 2 | 2 | 2 |
| 5 | 5 | 45 | 5 | 1 |
+----+--------+--------+-------------+----------+
Now, I need to update the TargetPrice to minimum of Price1 and Price2 for any row whose Quantity is 0
I have tried:
UPDATE Inventory SET
TargetPrice= MIN(Price1,Price2)
WHERE Quantity >0
However, MySQL complains about the usage of MIN() function. I know it is expecting MIN() to work on the data contained inside column, rather than taking MIN() of two columns of a specified row.
Anyway to achieve this other than cursors?
EDIT:
Price1 and Price2 can be null or 0 and in all these cases, it should be treated as infinity so that the other price gets to be minimum when compared against it.
Use LEAST instead of MIN:
UPDATE Inventory
SET TargetPrice = LEAST(Price1,Price2)
WHERE Quantity = 0
MIN is an aggregate function operating on a rowset, whereas LEAST operates on the list of arguments passed.
EDIT:
UPDATE Inventory
SET TargetPrice = LEAST(COALESCE(Price1, Price2), COALESCE(Price2, Price1))
WHERE Quantity = 0
You can use COALESCE to handle NULL values.
EDIT2:
You can use NULLIF to handle 0 values:
UPDATE Inventory
SET TargetPrice = LEAST(COALESCE(NULLIF(Price1,0), Price2),
COALESCE(NULLIF(Price2,0), Price1))
WHERE Quantity = 0