mysql count groupings - mysql

CREATE TABLE `articles_entities` (
`id` CHAR(36) NOT NULL,
....
`created` DATETIME DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `created` (`created`)
) ENGINE=MYISAM DEFAULT CHARSET=utf8;
I am trying to create a query that gives me the count of records by day.. e.g
Day 1: 23
Day 2: 343
etc...
Please note the output is not the exact format I want, just a display of what data I want.

While writing the question I realised just how easy this is....
SELECT COUNT(*), DATE_FORMAT(created, '%Y%m%d') AS testgroup FROM articles_entities GROUP BY testgroup;

Related

How can I use a trigger to update several tables taking specific data from rows in a table being updated?

I have searched quite a bit and can't seem to find the answer to this. I am fairly new to MySQL and this is something I had previously written as a php script to update the individual tables, but would rather it update automatically on the database when the table changes.
When I update a table via a google script I then require about 6 different tables to be updated from different rows in the main table, by date, and each table requires data from a different column.
I know this is not the correct way to do it but I need the trigger to effectively do the following;
CREATE TRIGGER dash_1
ON global_summary AFTER UPDATE
UPDATE widget_dash_2 (date, metric)
WHERE inc_id=100 SELECT date, volume
FROM global_summary
WHERE (`date` = SUBDATE(CURDATE(), 1))
UPDATE widget_dash_2 (date, metric)
WHERE inc_id=101 SELECT date, volume
FROM global_summary
WHERE (`date` = SUBDATE(CURDATE(), 8))
This would be for one of the columns "volume" from table "global_summary", I then need to add up to another 5 updates such as;
UPDATE widget_dash_3 (date, metric)
WHERE inc_id=100 SELECT date, score
FROM global_summary
WHERE (`date` = SUBDATE(CURDATE(), 1))
UPDATE widget_dash_3 (date, metric)
WHERE inc_id=101 SELECT date, score
FROM global_summary
WHERE (`date` = SUBDATE(CURDATE(), 8))
Where "score" is another column in the table "global_summary".
Any guidance would be much appreciated. I have been looking for some guidance on this for days now and it has just made me more confused.
I'm assuming I need to do something with arrays and initially getting all data from the main table, but how can I then carve that up?
#sticky bit,
Unfortunately I have to put this data into these small tables, believe me I would much rather just pull it from global_summary directly.
CREATE TABLE `global_summary` (
`id` int(11) DEFAULT NULL,
`date` date DEFAULT NULL,
`volume` int(10) DEFAULT NULL,
`volume_problem` int(10) DEFAULT NULL,
`removed` int(10) DEFAULT NULL,
`score` int(10) DEFAULT NULL,
`error` int(10) DEFAULT NULL,
`total` int(10) DEFAULT NULL,
`previous` int(10) DEFAULT NULL,
`entryID` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
All the widget_dash tables;
CREATE TABLE `widget_dash_2` (
`inc_id` int(11) NOT NULL,
`date` date DEFAULT NULL,
`metric` int(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Thanks for your feedback so far, and yes I probably was confusing UPDATE with INSERT.

MySQL: best practice for querying last value before a certain date in a time series

I have the following table in MySQL:
CREATE TABLE `history` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`timestamp` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`code` CHAR(32) NOT NULL,
`value` FLOAT NULL DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE INDEX `timestamp_code` (`timestamp`, `code`),
INDEX `code` (`code`),
INDEX `timestamp` (`timestamp`)
) COLLATE='utf8_general_ci' ENGINE=InnoDB;
I would like to know what is the best practice in order to access the last available value before a certain date for a certain set of codes the most efficiently?
So far I came up with the following query:
SELECT h.* FROM history h
JOIN (
SELECT code, MAX(timestamp) as 'last_ts'
FROM history WHERE
timestamp < '2015-09-04 13:50:00' AND
code IN ('119813249', '12087792', '12087797',
'127012151', '131014335', '131014378',
'132757371', '15016059', '15016062',
'150250238', '153462747', '155802712',
'156974389', '162277696', '166330444',
'166483001', '167220356', '167264923',
'167867931', '172283682', '177539478',
'177583937', '177648754', '177649011',
'187532416', '189230667', '70273253',
'70342790', '79342386', '82460282',
'98693280', '98693380')
GROUP BY code) last_price
ON last_price.last_ts = h.timestamp
AND last_price.code = h.code
The query above works, but becomes slow as the number of entries in the table grows (100'000'000 rows).
You can download sample data to populate the table.
Create an index by code, timestamp - rather than timestamp, code. This would let mysql sort out codes before looking for the max timestamp per code - and should be much faster. Use explain for verifying that the index is used.
And if you create that index - you should not have to modify your query.

MySQL null dates are not filtered out by query

In a table, there are several date columns. some of them contain null, the others are set with valid dates.
This query returns 17 records (and it is correct):
SELECT * FROM table
This query returns 6 records (and it is correct):
SELECT * FROM table WHERE selected_column IS NULL
This query returns 17 records (and it is wrong, obviously):
SELECT * FROM table WHERE selected_column IS NOT NULL
Any explanations?
edit
The create table statment:
CREATE TABLE `contracts` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`start_date` date NOT NULL,
`end_date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=12323 DEFAULT CHARSET=utf8
Column with NULL value is not listed in where clause. It seems to be the only explanation.
Try Select selected_column from table where selected_column is not NULL

mysql select distinct date takes FOREVER on database w/ 374 million rows

I have a MYSQL DB with table definition like this:
CREATE TABLE `minute_data` (
`date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
`open` decimal(10,2) DEFAULT NULL,
`high` decimal(10,2) DEFAULT NULL,
`low` decimal(10,2) DEFAULT NULL,
`close` decimal(10,2) DEFAULT NULL,
`volume` decimal(10,2) DEFAULT NULL,
`adj_close` varchar(45) DEFAULT NULL,
`symbol` varchar(10) NOT NULL DEFAULT '',
PRIMARY KEY (`symbol`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8
It stores 1 minute data points from the stock market. The primary key is a combination of the symbol and date columns. This way I always have only 1 data point for each symbol at any time.
I am wondering why the following query takes so long that I can't even wait for it to finish:
select distinct date from test.minute_data where date >= "2013-01-01"
order by date asc limit 100;
However I can select count(*) from minute_data; and that finishes very quickly.
I know that it must have something to do with the fact that there are over 374 million rows of data in the table, and my desktop computer is pretty far from a super computer.
Does anyone know something I can try to speed up with query? Do I need to abandon all hope of using a MySQL table this big??
Thanks a lot!
When you have a composite index on 2 columns, like your (symbol, date) primary key, searching and grouping by a prefix of they key will be fast. But searching for something that doesn't include the first column in the index requires scanning all rows or using some other index.
You can either change your primary key to (date, symbol) if you don't usually need to search for symbol without date. Or you can add an additional index on date:
alter table minute_data add index (date)

Order by two fields - Indexing

So I've got a table with all users, and their values. And I want to order them after how much "money" they got. The problem is that they have money in two seperate fields: users.money and users.bank.
So this is my table structure:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(4) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(54) COLLATE utf8_swedish_ci NOT NULL,
`money` bigint(54) NOT NULL DEFAULT '10000',
`bank` bigint(54) NOT NULL DEFAULT '10000',
PRIMARY KEY (`id`),
KEY `users_all_money` (`money`,`bank`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_swedish_ci AUTO_INCREMENT=100 ;
And this is the query:
SELECT id, (money+bank) AS total FROM users FORCE INDEX (users_all_money) ORDER BY total DESC
Which works fine, but when I run EXPLAIN it shows "Using filesort", and I'm wondering if there is any way to optimize it?
Because you want to sort by a derived value (one that must be calculated for each row) MySQL can't use the index to help with the ordering.
The only solution that I can see would be to create an additional total_money or similar column and as you update money or bank update that value too. You could do this in your application code or it would be possible to do this in MySQL with triggers too if you wanted.