I am having a question about doing this filter in mysql.
I have a date with 3 dates.
1-start date; Ex: 10-04-2017
2-end date; Ex: 04-20-2017
3-date completion; Ex 23-04-2017
If the order is delivered between the start date and the end date it is on time and will record the completion date;
But if the order is delivered after it will record a date higher than the correct end date?
So I wanted to filter and list those orders that were delivered late.
What should I do?
Suppose that you have an orders table with 3 different dates as you mentioned in your post. Assume that your orders table have four columns (id, startDate, endDate, compDate) to keep it simple. Now SQL of your MySQL Database is given as:
CREATE TABLE `orders` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`startDate` datetime DEFAULT NULL,
`endDate` datetime DEFAULT NULL,
`compDate` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
Assume there are three records in your orders table, two of which are late orders that is they exceed the endDate :
/*Data for the table `orders` */
insert into `orders`(`id`,`startDate`,`endDate`,`compDate`) values
(1,'2017-04-10 00:00:00','2017-04-20 00:00:00','2017-04-23 00:00:00'),
(2,'2017-04-10 00:00:00','2017-04-20 00:00:00','2017-04-19 00:00:00'),
(3,'2017-04-10 00:00:00','2017-04-20 00:00:00','2017-04-22 00:00:00');
Now you need to run the following simple SQL statement with filter (compDate > endDate) to check for those orders that were delivered late:
SELECT * FROM orders WHERE compDate > endDate;
it will give you two late delivered records with id 1 and 3. (i.e., late orders.)
Click here to see the Sqlyog query snapshot that displays late orders
Hope this solves your problem.
Related
I have a MySQL DB table called 'purchases' populated with records of various transactions. I wish to find out what % of transactions have occurred on particular day of the week and was wondering how I would go about achieving that using SQL. I have a field in this table called 'submitted' which holds a standard unix timestamp for when the transaction was recorded.
What I have so far:
SELECT COUNT(DISTINCT DATE_FORMAT(submitted,%a)) FROM purchases;
My end goal is to create a table with % of all transactions on given days, Monday - Sunday.
My table structure is as follows:
CREATE TABLE IF NOT EXISTS `purchases` (<br />
`id` int(11) NOT NULL AUTO_INCREMENT,<br />
`orderinfo` varchar(50) NOT NULL,<br />
`amount` varchar(5) NOT NULL,<br />
`reference` varchar(15) NOT NULL,<br />
`name` varchar(50) NOT NULL,<br />
`address` varchar(100) NOT NULL,
`town` varchar(50) NOT NULL,<br />
`postcode` varchar(12) NOT NULL,<br />
`submitted` int(11) NOT NULL,<br />
UNIQUE KEY `id` (`id`)<br />
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Convert the time stamp into date and then take the COUNT, This will fetch count as well as percentage
SELECT date ( from_unixtime(submitted) ), count(*) as `count`, count(*)/(select count(*) from purchases)*100 as percentage
FROM purchases
GROUP BY date ( from_unixtime(submitted) );
You can get what you want with two nested queries like this (splitted in more lines and indented for better readability)
SELECT
DAYOFWEEK(FROM_UNIXTIME(`submitted`)),
100 * COUNT(*) /
(SELECT COUNT(*) from `purchases`)
FROM
`purchases`
GROUP BY
DAYOFWEEK(FROM_UNIXTIME(`submitted`))
Note that the inner query (SELECT COUNT(*) from purchases) is used to retrieve the total number of purchases since you want a percentage number.
mysql's DAYOFWEEK() returns not the name of the day but an index number from 1 to 7.
You can look here for reference for mysql date ant time functions:
http://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html
If you just need a query then you're done.
If you want to build a view with that query you can't because mysql doesn't allow nested SELECT in a view's definition.
You would then split the job in two views, one that just calculates the total number of records, and the second that calculates the percentage.
A final note about performance:
if you have a huge amount of records to process this is not performing very fast.
If you then plan to run the query very often this is not good.
In that case since submitted is most likely to be written just one time and never changed you may then consider to add another field on your table called submitted_dayofweek, type int.
When you update subitted, update also submitted_dayofweek storing DAYOFWEEK(FROM_UNIXTIME(submitted)).
Finally make sure submitted_dayofweek is indexed.
The query becomes
SELECT
`submitted_dayofweek`,
100 * COUNT(*) /
(SELECT COUNT(*) from `purchases`)
FROM
`purchases`
GROUP BY
`submitted_dayofweek`
and will run very fast at the price of a little more storage space used.
I browsed summaries for all 500+ answers related to this question but found no apparent SQL solution to my problem. Maybe there is none.
I wish to display a Top10 Companies by Hits on Company Profile from nnn to nnn time period.
MySQL Table to track hits on company profile
CREATE TABLE `hit_company` (
`id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT,
`hitdate` date NOT NULL DEFAULT '0000-00-00',
`customerid` mediumint(9) unsigned NOT NULL DEFAULT '0',
`organization` varchar(80) DEFAULT NULL,
`hitstamp` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`remote_addr` varchar(20) DEFAULT NULL,
`hittime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=123456 ;
The MySQL query for a 24 hour report looks like this:
SELECT hitstamp,hitdate,customerid,organization, COUNT(organization) AS 'count' FROM hit_company
WHERE hitstamp >= '2014-01-12 21:23' AND hitstamp <= '2014-01-13 21:23'
GROUP BY customerid ORDER BY count DESC LIMIT 10
This yields a Top10. The problem is that I am getting hits significantly inflated by varying remote_addr who refresh their company profile page and thus artificially increase their hit counter. I only want to count 1 vote per IP per company within the report time range.
I have considered but am not sure how to code something similar to:
WHERE COUNT(remote_addr < 2)
or
GROUP BY customerid, remote_addr HAVING 'votes' < 2
... so that the same IP address is not counted more than once per company in the final result.
What is the SQL to do this?
If there is no sql, what is the optimum solution in php/mysql ?
Thank you.
Note
While this report spans 24 hours, other reports span from 12 hours to 30 days to all time.
SELECT whatever FROM (
SELECT whatever FROM hit_company
WHERE hitstamp >= whatever
GROUP BY organization, remoteaddr
) GROUP BY customerid ORDER BY count
Hand written not tested. The basic idea is use subquery. It'll be very slow if computing on large data.
I have tried to Google this so I didn't have to ask, as i'm sure this is a simple task...
I am building an E-commerce site and would like to add the date and time a product is added into the product database?
Apologies if this is simple, but i have researched everywhere else first.
Thanks
This can just be part of your database architecture:
ALTER TABLE `products` ADD `created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
This will automatically add a timestamp to the column created whenever a row is created. For more information, try this: Automatic Initialization and Updating for TIMESTAMP
Obviously, in this case the table is called products and you would need to change it to whatever your table name is.
UPDATE
To update all existing records at the same time, just run:
UPDATE `products` SET `created` = NOW()
If you want to be more specific use:
UPDATE `products` SET `created` = NOW() WHERE `created` = '0000-00-00 00:00:00'
Method1 : Pass the Current DateTime as parameter to the Insert
Method2: Set the default value for the date time column in Product table
Background
I have a MySQL db with around 16 million records. There are 2 columns created_at and updated_at which are presently in datetime format.
The Problem
I'd like to change this to UNIX Timestamp by converting all the values and updating the records with the new values.
I know how to do this with PHP in loops, but is there a way to perform this update by executing a single query in MySQL?
As it'll be a one time change; you can proceed this way:
Create new columns with INT datatypes and name them, say, created and updated.
ALTER TABLE `nameOfTable`
ADD COLUMN `created` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `created_at`,
ADD COLUMN `updated` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `updated_at`;
Update table:
UPDATE `nameOfTable`
SET `created` = UNIX_TIMESTAMP( `created_at` ),
`updated` = UNIX_TIMESTAMP( `updated_at` );
Remove the older columns and rename newer ones back to created_at and updated_at.
Alternative way:
Set the DATETIME columns to VARCHAR field.
Update using the query:
UPDATE `nameOfTable`
SET `created_at` = UNIX_TIMESTAMP( `created_at` ),
`updated_at` = UNIX_TIMESTAMP( `updated_at` );
Change the columns to INT.
hjpotter92's answer helped a lot.
But in my case it did not solve the problem right away, since the dates I had stored were in a format not accepted as an argument by UNIX_TIMESTAMP.
So I had to first convert it to an accepted format. After some research I got to the following query that made it:
UPDATE tableName set newFieldName = UNIX_TIMESTAMP(STR_TO_DATE(CAST(priorFieldName AS CHAR), '%m/%d/%y'));
I am working with a database that has a table called date, which contains a separate field for day, month, year. Clearly this is not ideal when I am trying to run comparisons, etc. I am wondering is it possible for me to add a DateTime field to each row of this table and insert a concatenated string into the new field from the existing day, month, year fields.
I am quite sure its possible, I'm just wondering if anyone might be able to point me in the right direction on how to achieve this?
Below is the current date table: (i know)
CREATE TABLE IF NOT EXISTS `date` (
`deposition_id` varchar(11) NOT NULL default '',
`day` int(2) default NULL,
`month` int(2) default NULL,
`year` int(4) default NULL,
PRIMARY KEY (`deposition_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
first use alter table query:
alter table date add column datetimefield datetime NOT Null
then
use update query with self join on date and update datetimefield with concat on date,month, year column values.
Try this (untested) -
UPDATE date d SET d.datetime = (SELECT CONCAT('-','year','month','day') from date d1 where d1.id = d.id);
What is the problem, I don't understand? Alter the table, add new DATE column and then populate it with a string "yyyy-mm-dd" using CONCAT mysql function or whatever.