Splitting date and time then transfer them to their new respective columns - php

I have a website which have a date and time combined in the start of meeting and end of meeting.
Meeting_start
2019-04-26 11:39:15
I already created new columns for date and time. How can I split the existing date and time then transfer them to their new respective columns?
Ps. I'm looking for SQL codes.

You can simply use the date and time functions available in mySQL
set #d='2019-04-26 11:39:15';
select date(#d),time(#d);
Will output
+------------+----------+
| date(#d) | time(#d) |
+------------+----------+
| 2019-04-26 | 11:39:15 |
+------------+----------+
Assuming that the existing column is called meeting_start and a table called TABLE you could then do
update `TABLE` set `date_col`=date( `meeting_start` ), `time_col`=time( `meeting_start` );
A simple table schema to illustrate how to update the new fields
mysql> describe `so_datetime_fudge`;
+--------------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(50) | YES | | NULL | |
| meeting_start | datetime | YES | | NULL | |
| meeting_start_date | date | YES | | NULL | |
| meeting_start_time | time | YES | | NULL | |
+--------------------+------------------+------+-----+---------+----------------+
A snapshot of the table with 3 rows of dummy data
mysql> select * from so_datetime_fudge;
+----+-----------------------+---------------------+--------------------+--------------------+
| id | name | meeting_start | meeting_start_date | meeting_start_time |
+----+-----------------------+---------------------+--------------------+--------------------+
| 1 | The First of Too Many | 2019-05-27 16:48:30 | NULL | NULL |
| 2 | Holy Cow Batman | 2019-05-27 16:54:56 | NULL | NULL |
| 3 | The End is Nigh | 2019-05-27 16:55:22 | NULL | NULL |
+----+-----------------------+---------------------+--------------------+--------------------+
Then running this query:
update `so_datetime_fudge` set `meeting_start_date`=date( `meeting_start` ), `meeting_start_time`=time( `meeting_start` );
Running the same SELECT query after the update
mysql> select * from so_datetime_fudge;
+----+-----------------------+---------------------+--------------------+--------------------+
| id | name | meeting_start | meeting_start_date | meeting_start_time |
+----+-----------------------+---------------------+--------------------+--------------------+
| 1 | The First of Too Many | 2019-05-27 16:48:30 | 2019-05-27 | 16:48:30 |
| 2 | Holy Cow Batman | 2019-05-27 16:54:56 | 2019-05-27 | 16:54:56 |
| 3 | The End is Nigh | 2019-05-27 16:55:22 | 2019-05-27 | 16:55:22 |
+----+-----------------------+---------------------+--------------------+--------------------+
But, if you create a VIEW of the table you can structure this how you like and the underlying data remains unchanged
CREATE VIEW `vw_datetime_fudge` AS select
`id`,
`name`,
date( `meeting_start` ) as `meeting_start_date`,
time( `meeting_start` ) as `meeting_start_time`
from `so_datetime_fudge`;
mysql> select * from `vw_datetime_fudge`;
+----+-----------------------+--------------------+--------------------+
| id | name | meeting_start_date | meeting_start_time |
+----+-----------------------+--------------------+--------------------+
| 1 | The First of Too Many | 2019-05-27 | 16:48:30 |
| 2 | Holy Cow Batman | 2019-05-27 | 16:54:56 |
| 3 | The End is Nigh | 2019-05-27 | 16:55:22 |
+----+-----------------------+--------------------+--------------------+

<?php
$subject = 'Meeting_start 2019-04-26 11:39:15';
$pattern = '/(\d\d\d\d\-\d\d\-\d\d).*(\d\d\:\d\d\:\d\d)/U';
preg_match_all($pattern,$subject,$matches);
$date = $matches[1][0];
$time = $matches[2][0];
echo $date . '<br>' . PHP_EOL;
echo $time . '<br>' . PHP_EOL;
gives result
2019-04-26<br>
11:39:15<br>

You can use DateTime::format method
$date = new DateTime('2019-04-26 11:39:15');
$timeString = $date->format('H:i:s');
$dateString = $date->format('Y-m-d');

Related

How do I merge all product tables while adding new column?

Summary
I have many tables that hold product information. The tables are all named like this:
p_productCategory
Here is some real data (showing only three for space)
+---------------------+
| Tables_in_global |
+---------------------+
| orders |
| p_audio_buzzers |
| p_audioaccessories |
| p_batteries_primary |
+---------------------+
The Task At Hand
I need to consolidate all these tables into ONE table. They all have the same column names:
+--------------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------------------------+--------------+------+-----+---------+-------+
| Datasheets | varchar(128) | YES | | NULL | |
| Image | varchar(85) | YES | | NULL | |
| DigiKey_Part_Number | varchar(46) | YES | | NULL | |
| Manufacturer_Part_Number | varchar(47) | YES | | NULL | |
| Manufacturer | varchar(49) | YES | | NULL | |
| Description | varchar(34) | YES | | NULL | |
| Quantity_Available | int(11) | YES | | NULL | |
| Factory_Stock | bit(1) | YES | | NULL | |
| Unit_Price | decimal(9,5) | YES | | NULL | |
| qty | bit(1) | YES | | NULL | |
| Minimum_Quantity | int(11) | YES | | NULL | |
| Packaging | varchar(4) | YES | | NULL | |
+--------------------------+--------------+------+-----+---------+-------+
Also, I need to add a new column "category", which would be the table name, ie: audioaccessories, batteries_primary
Question:
How would I go about making a new "products" table, and inserting all the records from all the tables prefaced with a p_ ?
Thank you for looking. I am stuck. I looked at some other "merge table" questions on here, but none were similar enough for me to use.
Write a query by using UNION between all the tables. Make sure to statically add "category" for each projection. Attach the query block right after CREATE TABLE segment.
Example:CREATE TABLE new_table_name AS SELECT *,'audio_buzzers' AS category FROM p_audio_buzzers UNION SELECT *,'audioaccessories' AS category FROM p_audioaccessories UNION SELECT *,'batteries_primary' AS category FROM p_batteries_primary

SQL Union 1 Column within Larger Query with Laravel ORM?

I'm currently storing addresses for multiple different objects. So there is addresses for jobs, companies, etc.
I want to be able to get all addresses.* and a union of jobs.job_title & companies.company_name to select an object_name for each addresses record.
Address.php (Model)
static $object_type = [
1 => 'Company',
2 => 'Job',
];
static public function getObjectTypes() {
return self::$object_type;
}
static public function getObjectTypeName($key) {
return self::$object_type[$key];
}
static public function getAddresses(){
$addresses = Address::select(
'addresses.*'
)->where('addresses.soft_deleted', 0);
$addresses->limit(20);
return $addresses->get();
}
The current schema for addresses table:
+-------------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+---------------------+------+-----+---------+----------------+
| id | int(12) unsigned | NO | PRI | NULL | auto_increment |
| object_id | int(12) | YES | MUL | 0 | |
| object_type | tinyint(3) | YES | | 1 | |
| address | varchar(255) | YES | | NULL | |
| soft_deleted | tinyint(3) unsigned | YES | | 0 | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL | |
+-------------------+---------------------+------+-----+---------+----------------+
The current schema for jobs table:
+-----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+----------------+
| id | int(12) unsigned | NO | PRI | NULL | auto_increment |
| company_id | int(12) | YES | | 0 | |
| job_title | varchar(99) | YES | | NULL | |
| soft_deleted | tinyint(3) unsigned | YES | | 0 | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL |
+-----------------+---------------------+------+-----+---------+----------------+
The current schema for companies table:
+-----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+---------------------+------+-----+---------+----------------+
| id | int(12) unsigned | NO | PRI | NULL | auto_increment |
| company_name | varchar(99) | YES | | NULL | |
| soft_deleted | tinyint(3) unsigned | YES | | 0 | |
| created_at | datetime | NO | | NULL | |
| updated_at | datetime | NO | | NULL |
+-----------------+---------------------+------+-----+---------+----------------+
My question is: How would I create the union and return the data needed based on the above structure?
Here is a SQLFiddle of what I think you are after. This is a very simplified schema to illustrate what is being done:
addresses
id | objectId | objectType | address
1 | 1 | 1 | 4657
2 | 1 | 3 | 3465
3 | 2 | 4 | 4536
4 | 1 | 2 | 3098
5 | 2 | 1 | 5647
6 | 2 | 2 | 8989
7 | 1 | 4 | 4563
8 | 2 | 3 | 2345
companies
id | name
1 | 'Acme Anvils'
2 | 'McBarfles'
3 | 'Noke'
4 | 'Stab Mart'
jobs
id | companyId | title
1 | 4 | 'Fly Swatter'
2 | 3 | 'Palm Greaser'
3 | 2 | 'McBarfle Burger Tender'
4 | 1 | 'Shill'
Assuming that objectType 1 = Company and objectType 2 = Job:
SELECT
'Company' AS objectType,
c.name,
a.address
FROM addresses a
INNER JOIN companies c
ON a.objectId = c.id
WHERE a.objectType = 1
UNION ALL
SELECT
'Job' AS objectType,
j.title,
a.address
FROM addresses a
INNER JOIN jobs j
ON a.objectId = j.id
WHERE a.objectType = 2
This breaks the joins up into sections based on the objectType in the addresses table, then UNION ALLs the results together to get the final list of addresses and object names:
objectType | name | address
Company | Acme Anvils | 4657
Company | Noke | 3465
Company | McBarfles | 3098
Company | Stab Mart | 4563
Job | Shill | 4536
Job | Fly Swatter | 5647
Job | Palm Greaser | 8989
Job | McBarfle Burger Tender | 2345
Note that you would have to manually add additional queries to be UNION ALLed for each possible value of objectType.

Not duplicate values ON DUPLICATE KEY UPDATE

I'm entering data in the database, but when the value of the slug and the site is duplicated it must update. But I can not succeed every time it adds a new line with the repeated data.
mysql;
+------------+--------------+------+-----+-----------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+-----------+-------+
| id_tag | int(11) | NO | PRI | None | |
| nome_tag | varchar(200) | NO | | None | |
| slug_tag | varchar(200) | NO | | None | |
| usuario_tag| int(3) | NO | | None | |
+------------+--------------+------+-----+-----------+-------+
DATA;
+------------+--------------+---------+------------+
| id_tag | nome_tag | slug_tag| usuario_tag|
+------------+--------------+---------+------------+
| 1 | Maria | maria | 1 |
| 2 | Car | car | 1 |
| 3 | Musa | musa | 1 |
| 4 | Tota | tota | 1 |
| 5 | Maria | maria | 1 |
+------------+--------------+------+-----+---------+
$vai = $conn->prepare("INSERT INTO tab_tags (nome_tag, slug_tag, usuario_tag) VALUES('$nome_tag', '$slug_tag', $usuario_tag) ON DUPLICATE KEY UPDATE slug_tag = '$slug_tag'");
$vai->execute();
var_dump($vai->queryString);
string 'INSERT INTO tags (nome_tag, slug_tag, usuario_tag) VALUES('Maria', 'maria', 1) ON DUPLICATE KEY UPDATE slug_tag = 'maria'' (length=148)
How do I duplicate it does not, I would like to do an Update, but he always doubles the data.
You need an UNIQUE index on columns nome_tag and slug_tag:
ALTER TABLE tab_tags ADD UNIQUE INDEX `nome_slug` (`nome_tag`, `slug_tag`)

strange behavior of query

I have the table below:
+-------------+------------------+------+-----+-------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+-------------------+----------------+
| category_id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| title | varchar(64) | NO | | NULL | |
| description | text | NO | | NULL | |
| created_on | timestamp | NO | | CURRENT_TIMESTAMP | |
| updated_on | timestamp | YES | | NULL | |
+-------------+------------------+------+-----+-------------------+----------------+
I needed to delete some records according to the date created and executed a set of queries:
mysql> select created_on from categories limit 10;
+---------------------+
| created_on |
+---------------------+
| 2013-01-14 09:26:21 |
| 2012-08-15 11:18:38 |
| 2012-09-06 06:44:46 |
| 2012-09-06 23:27:14 |
then
mysql> select date('2013-01-14 09:26:21');
+-----------------------------+
| date('2013-01-14 09:26:21') |
+-----------------------------+
| 2013-01-14 |
+-----------------------------+
and finally I got:
mysql> select DATE('created_on') from categories limit 10;
+--------------------+
| DATE('created_on') |
+--------------------+
| NULL |
| NULL |
| NULL |
| NULL |
As you can see the date wasn't converted correctly. In about 10 minutes is worked ok:
mysql> select date(created_on) from categories limit 10;
+------------------+
| date(created_on) |
+------------------+
| 2013-01-14 |
| 2012-08-15 |
| 2012-09-06 |
| 2012-09-06 |
I'm sure that the data were intact while I was running the queries.
So my question:
Can anybody explain why date function showed different results on the same input?
You have to use::
select DATE(created_on) from categories limit 10;
By using the inverted comma, you are asking the database to treat 'created_on' as parameter, and since it cannot be converted to date type, you are getting null
select DATE('created_on') from categories limit 10;
String versus column:
select DATE(created_on) from categories limit 10;

SQL Query using MySQL sample employee database

I have a problem making an advanced (for me) query.
I am trying to get the first name, last name, title, department name, and first and last name of the manager. I am using this SQL in PHP if for some reason you needed to know. I limit to 10 because the database is enormous. I need only the entry for the employees latest data. They have more than one entry because of job promotions, etc.
I included everything I think you would need to understand my problem. Thanks if you can help.
mysql>
SELECT DISTINCT employees.first_name, employees.last_name,
titles.title, departments.dept_name, z.first, z.last
FROM employees, dept_emp, departments, titles,
(
SELECT employees.first_name AS first, employees.last_name AS last
FROM employees, dept_emp, dept_manager
WHERE
employees.emp_no = dept_emp.emp_no
AND dept_manager.emp_no = dept_emp.emp_no
) AS z
WHERE
employees.emp_no = dept_emp.emp_no
AND dept_emp.dept_no = departments.dept_no
AND titles.emp_no = employees.emp_no
LIMIT 10;
+------------+-----------+-----------------+-------------+-----------+--------------+
| first_name | last_name | title | dept_name | first | last |
+------------+-----------+-----------------+-------------+-----------+--------------+
| Georgi | Facello | Senior Engineer | Development | Margareta | Markovitch |
| Georgi | Facello | Senior Engineer | Development | Vishwani | Minakawa |
| Georgi | Facello | Senior Engineer | Development | Ebru | Alpin |
| Georgi | Facello | Senior Engineer | Development | Isamu | Legleitner |
| Georgi | Facello | Senior Engineer | Development | Shirish | Ossenbruggen |
| Georgi | Facello | Senior Engineer | Development | Karsten | Sigstam |
| Georgi | Facello | Senior Engineer | Development | Krassimir | Wegerle |
| Georgi | Facello | Senior Engineer | Development | Rosine | Cools |
| Georgi | Facello | Senior Engineer | Development | Shem | Kieras |
| Georgi | Facello | Senior Engineer | Development | Oscar | Ghazalie |
+------------+-----------+-----------------+-------------+-----------+--------------+
10 rows in set (0.00 sec)
The database is the employees database from mysql.com:
http://dev.mysql.com/doc/index-other.html
mysql> desc departments;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| dept_no | char(4) | NO | PRI | NULL | |
| dept_name | varchar(40) | NO | UNI | NULL | |
+-----------+-------------+------+-----+---------+-------+
2 rows in set (0.22 sec)
mysql> desc dept_emp;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| emp_no | int(11) | NO | PRI | NULL | |
| dept_no | char(4) | NO | PRI | NULL | |
| from_date | date | NO | | NULL | |
| to_date | date | NO | | NULL | |
+-----------+---------+------+-----+---------+-------+
4 rows in set (0.20 sec)
mysql> desc dept_manager;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| dept_no | char(4) | NO | PRI | NULL | |
| emp_no | int(11) | NO | PRI | NULL | |
| from_date | date | NO | | NULL | |
| to_date | date | NO | | NULL | |
+-----------+---------+------+-----+---------+-------+
4 rows in set (0.21 sec)
mysql> desc employees;
+------------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+---------------+------+-----+---------+-------+
| emp_no | int(11) | NO | PRI | NULL | |
| birth_date | date | NO | | NULL | |
| first_name | varchar(14) | NO | | NULL | |
| last_name | varchar(16) | NO | | NULL | |
| gender | enum('M','F') | NO | | NULL | |
| hire_date | date | NO | | NULL | |
+------------+---------------+------+-----+---------+-------+
6 rows in set (0.32 sec)
mysql> desc salaries;
+-----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------+------+-----+---------+-------+
| emp_no | int(11) | NO | PRI | NULL | |
| salary | int(11) | NO | | NULL | |
| from_date | date | NO | PRI | NULL | |
| to_date | date | NO | | NULL | |
+-----------+---------+------+-----+---------+-------+
4 rows in set (0.34 sec)
mysql> desc titles;
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| emp_no | int(11) | NO | PRI | NULL | |
| title | varchar(50) | NO | PRI | NULL | |
| from_date | date | NO | PRI | NULL | |
| to_date | date | YES | | NULL | |
+-----------+-------------+------+-----+---------+-------+
4 rows in set (0.60 sec)
I am trying to get the first name, last name, title, department name, and first and last name of the manager
Using the theory (but it's probably not optimized if you have large tables), do it step by step. Assuming you have a $date PHP variable that contains a date (like the result from date('Y-m-d 00:00:00')), or otherwise you may use MySQL's date.
1/ get employees' identity:
SELECT
e.first_name,
e.last_name
FROM
employees AS e
WHERE
1
2/ add his/her current title
SELECT
e.first_name,
e.last_name,
t.title
FROM
employees AS e,
titles AS t
WHERE
e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date'
3/ get his/her current department (from dept_emp) and retrieve the department's name
SELECT
e.first_name,
e.last_name, t.title,
d.dept_name
FROM
employees AS e,
titles AS t,
dept_emp AS de,
departments as d
WHERE
e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date'
AND
e.emp_no=de.emp_no AND de.from_date<='$date' AND de.to_date>='$date'
AND
d.dept_no=de.dept_no
4/ get the department's manager (from dept_manager) and retrieve his/her name (from employees)
SELECT
e.first_name AS empFN,
e.last_name AS empLN,
t.title AS empT,
d.dept_name AS dept,
em.first_name AS manFN,
em.last_name AS manLN
FROM
employees AS e,
titles AS t,
dept_emp AS de,
departments as d,
dept_manager AS dm,
employees AS em
WHERE
e.emp_no=t.emp_no AND t.from_date<='$date' AND t.to_date>='$date'
AND
e.emp_no=de.emp_no AND de.from_date<='$date' AND de.to_date>='$date'
AND
d.dept_no=de.dept_no
AND
em.emp_no=dm.emp_no AND dm.from_date<='$date' AND dm.to_date>='$date'
AND
de.dept_no=dm.dept_no
There you can append a LIMIT (and an ORDER BY probably, you don't know which results will be picked in case of a limit), and/or add in the WHERE an emp_no for the employee(s) you want to have info about. Not tested though, but it's mainly to let you understand how to build the request.
This is theory, and this request is probably be as heavy to process as the one you wrote. Since you use SQL with PHP, it may be better to retrieve only the primary keys you're interested in, then send short requests to retrieve the information you want. Something like that I mean (using fake functions but the spirit's here):
$dateString="from_date<='$date' AND to_date>='$date'";
$qe=query("SELECT emp_no, first_name, last_name, dept_no FROM employees, dept_emp WHERE dept_emp.emp_no=employees.emp_no LIMIT 10 ORDER BY emp_no DESC");
while($r=fetch($qe)) {
$qt=fetch(query("SELECT title FROM titles WHERE emp_no=".$qe['emp_no']." AND ".$dateString));
$qd=fetch(query("SELECT dept_name FROM departments WHERE dept_no=".$qe['dept_no']." AND ".$dateString));
$qm=fetch(query("SELECT first_name, last_name FROM employees AS e, dept_manager AS dm WHERE dept_no=".$qe['dept_no']." AND e.emp_no=dm.emp_no AND ".$dateString));
//echo/process here
}
Hope this helps :)

Categories