is there a way to update multiple colomn with spesific part? - mysql

I have a table and inside there's a birth date, one of the worker serial number is almost the same as the birth date and since some of the serial number data is not the same as their birth date I wanted to update those date as the same as their serial number.
I use this kind of code
UPDATE worker
SET birthdate = MID(NIP,1,8)
where (MID(NIP,1,8)
<>concat(MID(TGLLHR,1,4),MID(TGLLHR,6,2),MID(TGLLHR,9,2)));
the 3rd line is for searching birthdate that not the same as serial number
the 2nd line is the one I wanted to change instead of getting output like 1996-08-01 the one that I got just like 19960801... I wanted to change it like date format
For example if one of them have serial number 19961101013 and their birth date is 1995-11-03 I wanted to change their birth date as same as the serial number like 1996-11-01

You can use couple or REPLACE/CONVERT method to check data matching between birthdate and NIP and then UPDATE data accordingly. The following script will help you to update your data accordingly.
Note: UPDATE is a risky command. Please try with your test data first.
UPDATE worker
SET birthdate = CONVERT(LEFT(CONVERT(NIP,CHAR),8) , DATE)
WHERE REPLACE(CONVERT(birthdate, CHAR),'-','') <> LEFT(CONVERT(NIP,CHAR),8)
The above script will only UPDATE records that has mismatch between birthdate and NIP value as you explained.

Related

Best database structure to store year with optional month and day?

I need to store birthdates, but for some people I only know the year and not the month and day. For month/day I will only allow either null or both of them filled out. How should I structure my database?
Currently I have this:
birth_year (YEAR)
birth_month (INT)
birth_day (INT)
Where birth_month and birth_day are nullable, but is it better to go for something like:
birth_date (DATE)
has_month_and_day (TINYINT/BOOL)
And set month and day to "01-01" if has_month_and_day is false?
Or this:
birth_year (YEAR)
bith_date (DATE)
And go for bith_date with the full date if everything is filled out and birth_year if birth_date is null?
Other suggestions? I still need to be able to tell if month and day was filled out so I can't just use one date column and set month and date to "01-01".
I will also need to filter by year and sort by date if that matters for the decision.
Thanks!
Edit // I found this in the MySQL docs. What do you think?
MySQL permits you to store dates where the day or month and day are
zero in a DATE or DATETIME column. This is useful for applications
that need to store birthdates for which you may not know the exact
date. In this case, you simply store the date as '2009-00-00' or
'2009-01-00'.
I would store them separately. You can always query on them as a full date using CONCAT and CAST 'mystring' as date if needed.

how to change the year of birth to age in .sql?

I have a sql file containing bYear and u_age column in users table.
I would like to know how I can change all the digits in bYear, such as 1986, 2000, to u_age such as 33, 19.
Thanks so much !!
If you are looking to update the table (not the file), you can just do:
update users set u_age = year(curdate()) - bYear;
curdate() gives you the current date, from which you can extract the year using the year() function.
Please note that this computation is not accurate at all: to compute an age, you need the entire date of birth (including month and day). The above computation behaves like the date of birth is actually the first day of year bYear.
If you are looking to update a sql file: as commented by Raymond Nijland, just don't. This is much more complicated and far less efficient. Instead, load the file in a table, update the table and then export it to a file

Mysql Function multiple entries in one cell

So I'm working on a schedule system for my job a basically i wanted to know if there is a way where mysql can do something like:
|Monday |tuesday|wendsday|total
|Dan |5am-7am |7am-6pm|6am-11am|
11am-2pm| |2pm-7pm |
5pm-12am|
where i can enter multiple shifts on 1 day for each person in the same cell if needed instead of the name repeating several times like:
Dan|5-4|
Dan|6-8|
and if there is a function to calculate total time in one cell with multiple shifts
There is a way (representing the data as string), but you wouldn't want to do this - you will loose all calculations, searches etc.
You should not try to represent the data in the database exactly as how it looks on paper.
I would make a table like this:
ShiftID|Person|StartTime|EndTime
Making StartTime & EndTime columns of type DATETIME, you will store not only the HH:mm of a shift's start, but also the day. This is helpful when you have a shift which starts on one day and ends in the next, like starting on Monday 2017-05-15 23:00 and ending on Tuesday 2017-05-16 02:00.
You can extract the date only from this filed using MySQL DATE() function and select only those entires which start OR end on this day.
To calculate the shift's duration you can use MySQL function TIMESTAMPDIFF()
You can even use DAYOFWEEK() to get if it is Monday, Tuesday, etc.
About duplicating the person's name - I would make another table, which will match users with their data to IDs an use ID in the column Person, but for a starter and if your data is not big and if speed is not an issue and if typo errors (like Den instead of Dan) are not a problem ... you could use the name directly in this table.
After storing the data in a table like this you could represent it as you wish in HTML (or print).
You can create a third table with the following columns:
person_id int,
start_time datetime,
end_time datetime
Where person_id would be foreign key to Person table and start_time and end_time would be datetime columns. You can then store multiple records for a person in this table and use MySQL's date functions with GROUP BY to generate the report similar to the one in question.

MS Access 2010: Extract unique values

first off: I know virtually nothing about MS Access but now I'm in a situation where I have to use it (dataset is too big for Excel). The data has column names like Customer_Name, Product Name, Amount, Date
Date refers to the last day of a month, so for example for February it's 28/02/2013. Now I want to compare the amount a customer bought in February to the amount he/she bought in January and calculate the difference. So far, I've been able to this by prompting the user to enter the date.
SELECT Data.Customer_Name,
Sum(IIf(Format(Date,"yymm")=[Startdate (yymm)?],Amount,0)) AS Amount_Startdate,
Sum(IIf(Format(Date,"yymm")=[Enddate (yymm)?],Amount,0)) AS Amount_Enddate,
Amount_Enddate-Amount_Startdate AS Difference
FROM Data
GROUP BY Data.Customer_Name;
This works but is it possible for Access to recognize which dates are in the column "Date" (there are only two distinct dates) so the user does not have to enter anything? Also, I tried to replace "Amount_Startdate" with a field that has the respective date in its name (e.g. "Amount_Feb2013") and played around with ampersand but it didn't work.
If you create a new table called tblValues with just 2 fields; ID and TDate (always try to avoid using reserved words like "Date", "System" or other words that Access already assigns a function to), you can fill it like this:
ID TDate
-- ---------
ST 1/31/2014
EN 2/28/2014
Then you could use the DLookup function to make this code generic:
SELECT Data.Customer_Name,
Sum(IIf(Format(Date,"yymm")=DLookup(Format(TDate, "yymm"), tblValues, "ID = 'ST'"),Amount,0)) AS Amount_Startdate,
Sum(IIf(Format(Date,"yymm")=DLookup(Format(TDate, "yymm"), tblValues, "ID = 'EN'"),Amount,0)) AS Amount_Enddate,
Amount_Enddate-Amount_Startdate AS Difference
FROM Data
GROUP BY Data.Customer_Name;
Then you could just update the table with the values you want to use as start and end dates whenever you want.

mysql query in between dates not working

I have the following mysql table:
tasks:
=====================
tid
status
desc
duedate
And i have the following records in that table:
records
===========================
1
active
Test description
08/15/2014
2
active
Another description
08/31/204
I am trying to get the days that there is a task for, in that particular month. I have the following query but when i run it it gets both records but "day" is null on both of them for some reason. Can someone please help me with this.
MYSQL QUERY
====================
SELECT DATE_FORMAT(due_date,'%d') AS day FROM tasks WHERE due_date BETWEEN '08/01/2014' AND '08/31/2014'
Try:
SELECT DAY(due_date) AS day
FROM tasks
WHERE due_date >= '2014-08'
AND due_date < '2014-09';
DAY() is a better function for what you want and I prefer using >= and < than BETWEEN for date comparisons, as it allows you to specify precise ranges more easily. Here, for example, you don't need to know the number of days in the month.
I have also used the default date format, which is preferable. If you need the, in my opinion, cray American date format, use DATE_FORMAT() in your SELECT.
This will only work with DATE, DATETIME and TIMESTAMP columns, which is how your due_date should be stored, preferably DATE.
UPDATE
To convert the VARCHAR column to DATE run:
UPDATE tasks SET due_date=STR_TO_DATE(due_date,'%m/%d/%Y')
Then change the type. Also remember to change your INSERT statements to use the default format.
You've got to convert those "date" strings to proper date values with STR_TO_DATE:
SELECT
DAY(STR_TO_DATE(due_date,'%m/%d/%Y')) AS day
FROM tasks
WHERE
STR_TO_DATE(due_date, '%m/%d/%Y')
BETWEEN STR_TO_DATE('08/01/2014' '%m/%d/%Y')
AND STR_TO_DATE('08/31/2014', '%m/%d/%Y')
else you're comparing strings instead.
Note:
It would be better to use a proper DATE or DATETIME column instead.
With the current VARCHAR format MySQL is unable to use indexes. That's very bad for performance.
You can convert your data by adding another column to your table:
ALTER TABLE tasks
ADD COLUMN new_due_date DATE;
Then you use an UPDATE statement to fill this new column
UPDATE tasks
SET new_due_date = STR_TO_DATE(due_date, '%m/%d/%Y');
If you don't need your old column anymore then you can delete this column and modify the new column to have the name of the old one. Then you will have your table with all your data in a DATE column.