How to update the 3rd element of nested elements (JSON like)? - mysql

I currently have a MySQL table as follow:
|| ID || Name || handling || enabled ||
|| 1 || bob || { 2 { 4, 7, 0.2 } 7 { 20.102, 3 } } || 1 ||
|| 2 || abc || { 6 { 4, 9, 0.6 } 7 { 20.102, 83 } } || 1 ||
|| 3 || xyz || { 2 { 4, 78, 0.2 } 7 { 20.102, 3 } } || 1 ||
I'm trying to find a way to do the following trick via an SQL query:
The third number there (7 for id 1, 9 for id 2, 78 for id 3) has to be changed to '30'. I'd do it all manually, but it's a table of approx. 5000 rows. And I "could" make a loop in c++ to do it all, but for some technical reasons, I rather have a SQL query.

If you know that the part to replace is always between first and second comma then you can do some string slicing, like this:
to change text between 1 and 2 comma:
UPDATE TEST_TABLE6
SET A = CONCAT(SUBSTRING_INDEX(A,',',1),',','30',SUBSTRING(A, LENGTH(SUBSTRING_INDEX(A,',',2))+1));
to change text between 7 and 8 comma:
UPDATE TEST_TABLE6
SET A = CONCAT(SUBSTRING_INDEX(A,',',7),',','30',SUBSTRING(A, LENGTH(SUBSTRING_INDEX(A,',',8))+1));

Related

MySQL Select groups of records based on change in value by comparing to previous group

Given the table, I am trying to select groups of records and sum the last column Class in each group. The rules of the grouping are slightly complicated and rows need to be compared to each other.
|| Seq || Time || Spec || Class
|| 1 || 8:05 || 0 || 5
|| 2 || 8:06 || 1 || 5
|| 3 || 8:07 || 2 ||10
|| 4 || 8:08 || 4 ||10
|| 5 || 8:09 || 3 || 5
|| 6 || 8:10 || 2 || 5
|| 7 || 8:11 || 6 || 5
|| 8 || 8:12 || 6 ||15
I need to group records based on the change in value (increase or decrease) in the Spec column. The required change in value is 2. So starting with row 1, the Spec is 0. It doesn’t increase by at least 2 until row 3. This is a valid group and I need to sum the Class field. The expected output is StartTime, StartSpec, EndTime, EndSpec, and TotalClass.
To determine the next group, I need to measure the change in value with the last row used in the previous group. As you can see, row 4 has immediately increased by 2 and so this one row is a valid group.
Expected Output:
||StartTime || StartSpec || EndTime || EndSpec || TotalClass
|| 8:05 || 0 || 8:07 || 2 || 20
|| 8:08 || 4 || 8:08 || 4 || 10
|| 8:09 || 3 || 8:10 || 2 || 10
|| 8:11 || 6 || 8:11 || 6 || 5
Can be done by using some intermediate variables, to detect the first and the last row in a group, as illustrated below.
Note that this will "auto-close" the last group, if it is not closed yet.
Also note, that for the use-cases like that, application-level solution
might be a more elegant option (as noted in the comments already).
Another option is to compute an explicit group discriminator (i.e. "gid"), at the data insertion time, and store it in the table itself, so that you can then query data in a standard way, w/o relying on any variables.
SELECT
MAX(startTime) as startTime,
MAX(startSpec) as startSpec,
MAX(endTime) as endTime,
MAX(endSpec) as endSpec,
SUM(class) as totalClass
FROM (
SELECT
/* Detect first and last rows in a group (when ordered by "seq") */
#first as isFirst,
#last:=(ABS(#prev-spec)>1 OR seq=(SELECT MAX(seq) FROM groups)) as isLast,
/* If this is a first row, set "startTime" and "startSpec" */
IF(#first,time,NULL) as startTime,
IF(#first,spec,NULL) as startSpec,
/* If this is a last row, set "endTime" and "endSpec" */
IF(#last,time,NULL) as endTime,
IF(#last,spec,NULL) as endSpec,
/* Start the next group */
IF(#last,#prev:=spec,NULL) as nextPrev,
IF(#last,(#gid:=#gid+1)-1,#gid) as gid,
/* Flip "first" */
#first:=#last as nextIsFirst,
/* Row "class" */
class
FROM
/* Declare some variables */
(SELECT #first:=TRUE,#last:=FALSE,#prev:=0,#gid:=0) init
CROSS JOIN Groups ORDER BY seq
) labeled GROUP BY gid;

Whats wrong with my if else statement

I have a $name variable containing a string, and when I test it, I never get the "Name should be between 2 and 40 characters" error even when it's less than 2 characters long or more than 40. Why?
if (strlen($name) < 2 && strlen($name) > 40) {
$nameError = 'Name should be between 2 and 40 characters';
}
How can the length be less than 2 and greater than 40? You want || ("or"), not && ("and").
if (strlen($name) < 2 || strlen($name) > 40) {
// -------------------^^

How can I calculated dates from another column and another table?

I have 2 tables:
table 1:
|| *handtool_id* || *maintenance_interval_value* || *unit_unit_id* || *handtool_last_date_of_maintenance* || *handtool_next_date_of_maintenance* ||
|| 1 || 1 || 5 || 2014-11-07 || ||
|| 2 || 1 || 6 || 2014-11-07 || ||
|| 3 || 4 || 4 || 2014-11-07 || ||
table 2:
|| *unit_id* || *unit_name* || *unit_value* || *unit_parent_id* ||
|| 1 || Minute || 1 || 1 ||
|| 2 || Hour || 60 || 1 ||
|| 3 || Day || 1440 || 1 ||
|| 4 || Week || 10080 || 1 ||
|| 5 || Month || 32767 || 1 ||
|| 6 || Year || 525949 || 1 ||
What is the right syntax for calculating the handtool_next_date_of_maintenance from maintenance_interval_value and from unit_unit_id? Thank you
I have to say, it's wrong, and very confusing to change your question like this. You should rollback this question to the one Andrew Jones answered Nov 3, accept and upvote his answer, and then ask a new question.
That said, this would appear to get you something like what you're after (although how you arrived at figures of 32767 and 525949 is beyond me !?!)
SELECT *
, h.handtool_last_date_of_maintenance
+ INTERVAL h.maintenance_interval_value
* u.unit_value MINUTE x
FROM handtools h
JOIN units u
ON u.unit_id = h.unit_unit_id;
Whenever you insert to B, you want to insert into A. This is a good use of a MySQL trigger. I'm assuming an auto increment for web_content_id.
DELIMITER //
CREATE TRIGGER new_language_id
AFTER INSERT ON B
FOR EACH ROW
BEGIN
INSERT INTO A (web_content_const, i18n_language_codes_i18n_language_codes_id)
VALUES ('SERVICES_HEADING', #i18n_language_codes_id),
('SERVICES_MAIN_TEXT', #i18n_language_codes_id),
('SERVICES_1_HEADING', #i18n_language_codes_id),
('SERVICES_1_TEXT', #i18n_language_codes_id);
END;//
DELIMITER ;

need an associative array from two mysql colums

i have a mysql table
||==========||==========||==========||
|| id || name || age ||
||==========||==========||==========||
|| 1 || joe || 10 ||
|| 2 || harry || 20 ||
|| 3 || jane || 45 ||
|| 4 || john || 56 ||
|| 5 || larry || 89 ||
|| 6 || henry || 23 ||
|| 7 || steve || 25 ||
|| 8 || eric || 56 ||
|| 9 || dave || 98 ||
|| 10 || mat || 56 ||
||==========||==========||==========||
i need the sql query that would make an associative array from this table and give me values like this
id=>age
1=>10
4=>56
i also need to make all the id's as a variable where there value would be the age like
$1 = 10
$4 = 56
or if i could add a prefix to the variables
$id_1 = 10
$id_4 = 56
thanks in advance
In PHP, mysql_fetch_assoc() takes the result of a query, and returns one row as an associative array. Call it repeatedly to get all rows.
if your using php for fetching your data you may use the function mysql_fetch_array example:
while($row = mysql_fetch_assoc($resource))
{
echo $row['name'].'<br>';
}
you may know more about mysql functions for php on this site: http://www.php.net/manual/en/book.mysql.php
$ids = '1, 4';
$sql = "select age from __TABLE__ where id in ( {$ids} )";
$link = mysql_connect('__SERVER__', '__DBUSER__', '__DB_PWD__') or die('connect error');
$db = mysql_select_db('__DBNAME__', $link) or die('db error');
$rs = mysql_query($sql, $link);
$result = array();
while($row = mysql_fetch_assoc($rs))
{
$result[] = $row;
}
extract(my_result($result));
var_dump($id_1);
var_dump($id_4);
function my_result($result, $prefix = 'id_')
{
$data = array();
foreach($result as $k => $v)
{
$data[$prefix . $v['id']] = $v['order_no'];
}
return $data;
}

Using Max in LINQ to SQL

Trouble with using Max in where clause of LINQ to SQL. Data below:
QID, Question, TypeID, Disable, VersionID, Sequence
1 Who's on 1st 1 False 1 1
2 Who's on 1st 1 False 2 1
3 What's on 2nd 1 False 1 2
4 What's on 2nd 1 False 2 2
5 I don't know 1 False 1 3
6 I don't know 1 False 2 3
I need to return a group of questions based on the Max of the VersionID as noted below. The result I expect from the data above would include rows 2, 4 & 6 ordered by Sequence.
IEnumerable<QUESTION> questions =
(from q in dataContext.QUESTIONs
where q.TypeID == Convert.ToInt16(ddlType.SelectedValue)
&& (q.Disable == null || q.bDisable == false)
&& (q.VersionID == dataContext.QUESTIONs.Max(q.nVersionID))
orderby q.Sequence ascending
select q);
Max() translates properly in linq-to-sql
Try
IEnumerable<QUESTION> questions = (from q in dataContext.QUESTIONs
let maxVersion = dataContext.QUESTIONs.Max(q.nVersionID)
where q.TypeID == Convert.ToInt16(ddlType.SelectedValue)
&& (q.Disable == null || q.bDisable == false)
&& (q.VersionID == maxVersion)
orderby q.Sequence ascending
select q);