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

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 ;

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;

How to avoid insert, delete, update anomaly in MySql

I have two tables like this
Table1: manager
=======================================
|| Id || MgrName || department ||
=========================================
|| 1 || mgr1 ||human resource ||
|| 2 || mgr2 ||marketing ||
|| 3 || mgr3 ||customer management ||
=========================================
Table2: employee
====================================
|| empid || empname || empmanager||
====================================
|| 1 || abc || mgr1 ||
|| 2 || xyz || mgr1 ||
|| 3 || def || mgr3 ||
=====================================
The thing is when I delete mgr1 in table1:manager. I also want to update employee table where empmanager is mgr1 by null. I don't want to use any trigger.
Please tell me proper way to design database and also to avoid this problem.
You should follow normalization rules to avoid anomalies while performing CRUD operations,
First Normal Form
Second Normal Form
Third Normal Form
please refer these links to apply normalization to you tables link 1 link 2

How to get total hour?

Name|| day||ActivityDate ||TimeIn || TimeOut ||
Ade || 20 || 2013-08-20 || 10:06:09 || 18:21:03 ||
Ade || 21 ||2013-08-27 || 11:00:34 || 18:06:56 ||
Ade || 22 || 2013-08-28 || 09:56:29 || 17:59:56 ||
This is my query :
select
tot=sum(DATEDIFF(hh ,TimeIn ,TimeOut )) as TotalHourAndMinute
from report
And error :
1582 - Incorrect parameter count in the call to native function
'DATEDIFF'
This is my table in datable..
I don't know how to get total hour like TimeOut-TimeIn..
fyi, i have a lot of data in this table.. not only this 3..
i hope you guys clear...
Name|| day||ActivityDate ||TimeIn || TimeOut || TotalHourAndMinute
Ade || 20 || 2013-08-20 || 10:00:00 || 18:30:00 || 8.5
Ade || 21 ||2013-08-27 || 11:00:34 || 18:06:56 || 7.something
Ade || 22 || 2013-08-28 || 09:56:29 || 17:59:56 || 7.something
i want it will be like this..
UPDATE
Well, if you're using MySQL the correct format for the function is this:
DATEDIFF(expr1,expr2)
More information about DATEDIFF, here. Also, all available time functions for MySQL are here.
But, if you want to see the difference in hours between two dates, use TIME_DIFF.
TIMEDIFF(expr1,expr2)
And documentation about TIME_DIFF here.
But strictly to your case, you should write your query like this:
SELECT tot = sum(HOUR(TIMEDIFF(TimeIn, TimeOut))) AS TotalHourAndMinute
FROM report
UPDATE:
Now, after updating your question I understand what you want.
The query you need to use is this:
SELECT
NAME,
DAY,
ActivityDate,
SUM(TIMEDIFF(TimeOut, TimeIn)) as TotalHourAndMinute
FROM REPORT
WHERE (TimeOut IS NOT NULL) AND (TimeIn IS NOT NULL)
GROUP BY NAME, DAY, ActivityDate
use:
SELECT HOUR(TIMEDIFF(TimeOut,TimeIn)) AS hour from report;
For more information visit this site.
If you aggregate time values you will get a result in seconds, to convert it back to time you call SEC_TO_TIME. This gives you:
SELECT
SEC_TO_TIME(SUM(TIMEDIFF(TimeOut, TimeIn))) AS TotalHourAndMinute
FROM
report

MySQL performance differences between a different "FROM" operator usage

Can someone please explain to me why this:
SELECT
A.id,
A.name,
B.id AS title_id
FROM title_information AS A
JOIN titles B ON B.title_id = A.id
WHERE
A.name LIKE '%testing%'
is considerably slower (6-7 times) than this:
SELECT
A.id,
A.name,
B.id AS title_id
FROM (SELECT id, name FROM title_information) AS A
JOIN titles B ON B.title_id = A.id
WHERE
A.name LIKE '%testing%'
I know it's probably hard to answer this question without knowing full details about the schema and MySQL configuration, but I'm looking for any generic reasons why the first example could be so significantly slower than the second?
Running EXPLAIN gives this:
|| *id* || *select_type* || *table* || *type* || *possible_keys* || *key* || *key_len* || *ref* || *rows* || *Extra* ||
|| 1 || SIMPLE || B || index || || id || 12 || || 80407 || Using index ||
|| 1 || SIMPLE || A || eq_ref || PRIMARY,id_UNIQUE,Index 4 || PRIMARY || 4 || newsql.B.title_id || 1 || Using where ||
and
|| *id* || *select_type* || *table* || *type* || *possible_keys* || *key* || *key_len* || *ref* || *rows* || *Extra* ||
|| 1 || PRIMARY || B || index || || id || 12 || || 80407 || Using index ||
|| 1 || PRIMARY || <derived2> || ALL || || || || || 71038 || Using where; Using join buffer ||
|| 2 || DERIVED || title_information || index || || Index 4 || 206 || || 71038 || Using index ||
UPDATE:
A.id and B.id are both PRIMARY KEYS, while A.name is an index. Both tables have around 50,000 rows (~15MB). MySQL configuration is pretty much a default one.
Not sure if that helps (or if it adds more to the confusion - as it does for me) but using more generic LIKE statement that is likely to have more matching fields (e.g. "LIKE '%x%'") makes the first query run considerably faster. On the other hand, using "LIKE '%there are no records matching this%'" will make the second query a lot faster (while the first one struggles).
Anyone can shed some light on what's going on here?
Thank you!
This is speculation (my powers of reading MySQL explain output are weaker than they should be, because I want to see data flow diagrams).
But here is what I think is happening. The first query is saying "Let's go through B and look up the appropriate value in A". It then looks up the appropriate value using the id index, then it needs to fetch the page and compare to name. These accesses are inefficient, because they are not sequential.
The second version appears to recognize the condition on name as being important. It is going through the name index on A and only fetching the matching rows as needed. This is faster, because the data is in the index and few pages are needed for the matching names. The match to B is then pretty simple, with only one row to match.
I am surprised at the performance difference. Usually, derived tables are bad performance-wise, but this is clearly an exception.

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;
}