MySQL cumulative sum grouped by date but exclude after certain date - mysql

I have a query involving dates that is really close to being complete, but I can't quite get the last part. The table columns are:
purchased TINYINT
purchased_date DATE
expired TINYINT
expiration_date DATE
The query I'm running is this:
SELECT
e_date,
num_interactions,
#runningTotal := #runningTotal + totals.num_interactions AS runningTotal
FROM
(SELECT
DATE(purchase_date) AS e_date,
COUNT(*) AS num_interactions
FROM domain_names AS d
WHERE purchased = 1
AND purchase_date != "0000-00-00"
GROUP BY DATE(d.purchase_date)) totals
ORDER BY e_date;
It works well, but I need one final adjustment. I need to exclude/subtract the names from the running total that were expired (based on expiration date) after the e_date.
In other words, if the running total shouldn't count a domain after the date it has expired. Thank you so much for any advice here. This is my first post here, so hopefully I've explained it clearly.
EDIT:
I've put together an MCRE:
CREATE TABLE IF NOT EXISTS `domain_names` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`purchased` tinyint(1) DEFAULT NULL,
`purchase_date` date DEFAULT NULL,
`expired` tinyint(1) DEFAULT NULL,
`expiration_date` date DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `index_domain_names_on_id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
INSERT INTO `domain_names` (`id`, `name`, `purchased`, `purchase_date`, `expired`, `expiration_date`) VALUES
('1', 'example1.com', '1', '2019-01-12', NULL, '2019-08-12'),
('2', 'example2.com', '1', '2019-01-12', NULL, '2020-10-12'),
('3', 'example3.com', '1', '2019-01-12', '1', '2019-10-12'),
('4', 'example4.com', '1', '2019-10-12', NULL, '2020-10-12'),
('5', 'example2.com', '1', '2019-03-19', NULL, '2020-03-19'),
('6', 'example3.com', '1', '2019-08-19', NULL, '2020-08-10'),
('7', 'example4.com', '1', '2019-11-28', NULL, '2020-10-12');
http://sqlfiddle.com/#!9/2d9f71/1/1

Here is a different approach not relying on variables and subqueries
SELECT
DATE(d.purchase_date),
COUNT(DISTINCT d.id) AS num_interactions,
COUNT(DISTINCT c.id) AS cumulative_sum_not_expired
FROM domain_names AS d
LEFT JOIN domain_names AS c ON (DATE(c.purchase_date) <= DATE(d.purchase_date)
AND c.purchased = 1
AND c.purchase_date != 0
AND c.expiration_date >= CURDATE())
WHERE d.purchased = 1
AND d.purchase_date != 0
GROUP BY 1
ORDER BY 1;
http://sqlfiddle.com/#!9/2d9f71/36/0
You can adjust the exclusion here :
c.expiration_date >= CURDATE()

if you need exclude expired domains, then you should add where clause expiration_date > CURDATE() to couning subquery or count only not expired domains COUNT(case when expiration_date > CURDATE() then 1 end)...
SET #runningTotal := 0;
SET #runningTotalNE := 0;
SELECT
e_date,
num_interactions,
#runningTotal := #runningTotal + totals.num_interactions AS runningTotal,
#runningTotalNE := #runningTotalNE + totals.notexpired AS runningTotalNotExpired
FROM
(SELECT
purchase_date AS e_date,
COUNT(*) AS num_interactions,
COUNT(case when expiration_date > CURDATE() then 1 end) AS notexpired
FROM domain_names AS d
WHERE purchased = 1
/*AND expiration_date > CURDATE()*/
AND purchase_date != "0000-00-00"
GROUP BY d.purchase_date) totals
ORDER BY e_date

Related

how insert registers of today from another table mysql

I'm trying to count the records in my "records" table and insert in results table but I just want to count today's records.
Below you will see some alternatives that I tried (I'm using MySQL), but I keep getting this error:
You have a syntax error in your SQL next to '' on line 2
INSERT INTO results (Data,total)
VALUES (now(), (SELECT COUNT(*) FROM records WHERE Data = now());
This SQL also causes an error:
INSERT INTO results (Data, total)
VALUES (now(), (SELECT COUNT(record.ID) AS day FROM record
WHERE date(Data) = date(date_sub(now(), interval 0 day));
and then
INSERT INTO resultS (Data,total)
VALUES (now(), (SELECT COUNT(*) FROM records
WHERE Data >= DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY));
And yet another attempt:
INSERT INTO results (Data, Total)
VALUES (now(), (SELECT COUNT(*) FROM records
WHERE DATE(Data)= CURRENT_DATE() - INTERVAL 1 DAY));
This is my sql config man:
CREATE TABLE `records`
(
`ID` char(23) NOT NULL,
`Name` varchar(255) NOT NULL,
`Total` int(255) NOT NULL,
`Data` date NOT NULL,
`QrCode` varchar(255) NOT NULL,
`City` varchar(255) NOT NULL,
`Device` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE `results`
(
`id` int(11) NOT NULL,
`total` int(11) NOT NULL,
`Data` date DEFAULT NULL,
`grown` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
You have defined grown column as not null so you cannot put there NULL.
My query works :
INSERT INTO results
VALUES (1, (SELECT COUNT(1) FROM records WHERE Data= now()), now(), 1);
You should define default value for grown column. Same situation you have with column id. You should define sequence for column id:
id NOT NULL AUTO_INCREMENT;
INSERT INTO results (Data, total)
SELECT CURRENT_DATE(), COUNT(*)
FROM records
WHERE DATE(Data) = CURRENT_DATE();

Mysql SUM by value in column

I have problem to get the proper result.
I have a table with registered time entries by date and user.
I also have a date table, that only consists of dates.
CREATE TABLE `jobbile_job_record` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`note` text,
`time_type` int(11) DEFAULT NULL,
`created_by` varchar(255) DEFAULT NULL,
`created` date DEFAULT NULL,
`jobbile_job_id` int(11) DEFAULT NULL,
`inserted` datetime DEFAULT CURRENT_TIMESTAMP,
`time_registered` decimal(11,2) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1145 DEFAULT CHARSET=latin1;
SET FOREIGN_KEY_CHECKS = 1;
I would like to get a result of
- date
- total time registered
- total time by user (registered)
I use the following query:
SELECT
date.date,
SUM(jobbile_job_record.time_registered) as 'total time',
SUM(jobbile_job_record.time_registered AND `jobbile_job_record`.`created_by` = '5713') as 'User 5713',
SUM(jobbile_job_record.time_registered AND `jobbile_job_record`.`created_by` = '5714') as 'User 5714'
FROM
date
LEFT JOIN jobbile_job_record
ON date.date = jobbile_job_record.created
WHERE
date.date BETWEEN '2019-11-01' AND '2019-11-30'
GROUP BY
date.date
ORDER BY
date.date ASC
Total_time works fine but the two SUM's with users filtered, is not summarized but counted.
Cant I use this method? Thanks!
I guess you need a case statement here -
SELECT
date.date,
SUM(jobbile_job_record.time_registered) as 'total time',
SUM(CASE WHEN `jobbile_job_record`.`created_by` = '5713' THEN jobbile_job_record.time_registered END) as 'User 5713',
SUM(CASE WHEN `jobbile_job_record`.`created_by` = '5714' THEN jobbile_job_record.time_registered END ) as 'User 5714'
FROM date
LEFT JOIN jobbile_job_record ON date.date = jobbile_job_record.created
WHERE date.date BETWEEN '2019-11-01' AND '2019-11-30'
GROUP BY date.date
ORDER BY date.date ASC

Solution for subquery in MySQL WHERE IN

I am trying to solve WHERE subquery or to find different solution.
What I am trying to achieve is based on this query:
SELECT c.orig_point_id,
(SELECT attempts
FROM
(SELECT
orig_carrier_id,
orig_point_id,
term_point_id,
term_route,
currency_sell,
is_special,
COUNT(*) AS attempts
FROM cdr
WHERE 1=1
AND start_time >= '2016-10-01 0:00:00'
AND start_time <= '2016-10-31 23:59:59'
GROUP BY orig_carrier_id, currency_sell) AS c0
WHERE c0.orig_carrier_id=3
AND c0.currency_sell="USD"
LIMIT 1) AS attempts,
(SELECT SPLIT(clear_number) as array
FROM
(SELECT
COUNT(*) as total,
clear_number,
orig_carrier_id,
currency_sell
FROM `cdr`
WHERE `start_time`>='2016-10-01 00:00:00'
AND start_time <= '2016-10-31 23:59:59'
GROUP BY `clear_number`
ORDER BY total DESC) AS c0
WHERE c0.orig_carrier_id=3
AND c0.currency_sell="USD"
LIMIT 1) AS splitted_number
FROM cdr AS c
GROUP BY c.orig_carrier_id, c.currency_sell;
SPLIT is a function. Query in that section finds a number(most frequent) and function splits it in ex. 12345,1234,123,12,1. Problem comes when i try to use that as IN subquery. When used directly mysql says functionality not supported. Looks like query is too complex.
When i alias subquery as a workaround it returns NULL, so workaround doesn't work and i believe its returning NULL because of the same reason that its not feasible.
SELECT
CONCAT_WS(" - ",country,region) AS route_name
FROM numbering_plan_external
WHERE
prefix IN(
SELECT array
FROM
(SELECT SPLIT(clear_number) as array
FROM
(SELECT
COUNT(*) as total,
clear_number,
orig_carrier_id,
currency_sell
FROM `cdr`
WHERE `start_time`>='2016-10-01 00:00:00'
AND start_time <= '2016-10-31 23:59:59'
GROUP BY `clear_number`
ORDER BY total DESC) AS c0
WHERE c0.orig_carrier_id=3
AND c0.currency_sell="USD"
LIMIT 1) AS splitted_number)
ORDER BY prefix DESC LIMIT 1) AS top_route
Am I doing anything wrong here, or is there different approach to achieve this. I can leave just split number and later through PHP find the route. It will require lots of queries depending on the results and I am trying to avoid it if possible.
Thanks in advance guys.
Some sample data
CREATE TABLE IF NOT EXISTS `numbering_plan_external` (
`id` int(11) NOT NULL,
`country` varchar(255) NOT NULL,
`region` varchar(255) DEFAULT NULL,
`prefix` varchar(50) NOT NULL,
`is_mobile` tinyint(1) NOT NULL DEFAULT '0',
`last_updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`min_sale_price_currency` char(3) CHARACTER SET latin1 COLLATE latin1_general_ci DEFAULT NULL,
`min_sale_price_amount` decimal(10,4) DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=14004 DEFAULT CHARSET=latin1;
INSERT INTO `numbering_plan_external`
(`id`, `country`, `region`,`prefix`, `is_mobile`, `last_updated`, `min_sale_price_currency`, `min_sale_price_amount`)
VALUES
(13047, 'Tunisia', '', '216', 0, '2016-02-17 12:30:44', NULL, NULL),
(13048, 'Tunisia', 'Mobile (ORANGE)', '2165', 1, '2016-02-17 12:30:44', NULL, NULL),
(13049, 'Tunisia', 'Mobile (ORASCOM)', '2162', 1, '2016-02-17 12:30:44', NULL, NULL),
(13050, 'Tunisia', 'Mobile (TUNTEL)', '21640', 1, '2016-02-17 12:30:44', NULL, NULL),
(13051, 'Tunisia', 'Mobile (TUNTEL)', '21641', 1, '2016-02-17 12:30:44', NULL, NULL),
(13052, 'Tunisia', 'Mobile (TUNTEL)', '2169', 1, '2016-02-17 12:30:44', NULL, NULL);
CREATE TABLE IF NOT EXISTS `cdr` (
`id` int(11) NOT NULL,
`orig_carrier_id` int(11) NOT NULL,
`orig_point_id` int(11) NOT NULL,
`term_carrier_id` int(11) NOT NULL,
`term_point_id` int(11) NOT NULL,
`clear_number` varchar(100) COLLATE latin1_general_ci NOT NULL,
`is_special` tinyint(1) NOT NULL DEFAULT '0',
`start_time` datetime NOT NULL,
`currency_sell` char(3) COLLATE latin1_general_ci NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=16385 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
INSERT INTO `cdr`
(`id`, `orig_carrier_id`, `orig_point_id`, `term_carrier_id`, `term_point_id`, `clear_number`, `is_special`, `start_time`, `currency_sell`) VALUES
(1, 3, 5, 0, 0, '21658502507', 0, '2016-10-17 00:02:04', 'USD'),
(2, 3, 5, 0, 0, '21658502507', 0, '2016-10-17 00:02:04', 'USD'),
(3, 3, 5, 0, 0, '21658502507', 0, '2016-10-17 00:03:56', 'USD'),
(4, 3, 5, 0, 0, '21658502507', 0, '2016-10-17 00:09:28', 'USD'),
(5, 3, 5, 0, 0, '21658502507', 0, '2016-10-17 00:16:35', 'USD');
IN considers values as a whole. Whatever your SPLIT() is doing, even though it returns a "csv", that entire list is considered one SINGLE value, e.g. it'll be parsed/executed as the equivalent
WHERE foo IN ('12345,1234,...')
WHERE foo='12345,1234,...'
instead of these
WHERE foo IN ('12345', '1234', '123', ...)
WHERE foo='12345' OR foo='1234' OR ...
You could try using MySQL's find_in_set() instead, which basically does what you want.
Using your sample data with this query:
SELECT
cdr.orig_point_id
, count(cdr.*) attempts
, group_concat(distinct npe.region) regions
FROM cdr
INNER JOIN numbering_plan_external npe
ON cdr.clear_number like concat(npe.prefix,'%') COLLATE latin1_general_ci
AND npe.region <> ''
WHERE cdr.orig_carrier_id=3
AND cdr.currency_sell='USD'
AND cdr.start_time >= '2016-10-01'
AND cdr.start_time < '2016-11-01'
GROUP BY
cdr.orig_point_id
;
Result:
| orig_point_id | attempts | regions |
|---------------|----------|----------------|
| 5 | 5 | Mobile (ORANGE)|
The join between those tables involves comparing the prefix to the starting characters of the clear_number. However you have a collation conflict so you need to specify the collation being used. Using LIKE is not the most efficient style of join condition and it could lead to performance issues as it doesn't make use of indexes. However it does demonstrate that a logical join does exist and that you do not need that split function (which is not good for a join either by the way).
I have left the remainder of my earlier question available for reference:
Query:
SELECT
orig_point_id
, count(*) attempts
FROM cdr
WHERE orig_carrier_id=3
AND currency_sell='USD'
AND start_time >= '2016-10-01'
AND start_time < '2016-11-01'
GROUP BY
orig_point_id
Results:
| orig_point_id | attempts |
|---------------|----------|
| 5 | 5 |
extracted for Original Query:
SELECT c.orig_point_id,
(SELECT attempts
FROM
(SELECT
orig_carrier_id,
orig_point_id,
term_point_id,
/* term_route, */
currency_sell,
is_special,
COUNT(*) AS attempts
FROM cdr
WHERE 1=1
AND start_time >= '2016-10-01 0:00:00'
AND start_time <= '2016-10-31 23:59:59'
GROUP BY orig_carrier_id, currency_sell) AS c0
WHERE c0.orig_carrier_id=3
AND c0.currency_sell="USD"
LIMIT 1) AS attempts
FROM cdr AS c
GROUP BY c.orig_carrier_id, c.currency_sell
Results:
| orig_point_id | attempts |
|---------------|----------|
| 5 | 5 |
Hopefully you can see that you do not need as much complexity in your query as you do now. I suspect that if we know more about the "expected result" we might be able to do it without the split function.

Return values even if null, 0 or not present

I want to create some reports so I can grab data quickly regarding our helpdesk, I am using GLPI which is running on MySQL 5.5
I have the below code and it returns some useful information but not enough so it can be put into a pretty stacked graph which is what he has requested. To get enough data to achieve this I need the urgency's that are zero and the days that are also zero, then I can convert the data into a table in Excel and build the graph.
Current Query:
SELECT DATE_FORMAT(date,'%d/%m/%Y') AS Date,Urgency,COUNT(*) as Tickets
FROM glpi.glpi_tickets
WHERE month(date)=month(NOW())
GROUP BY urgency ORDER BY date,urgency ASC;
This returns:
# Date, Urgency, Tickets
'07/06/2016', '3', '10'
'10/06/2016', '2', '1'
'14/06/2016', '1', '1'
'14/06/2016', '5', '1'
I would ideally like it to display as below:
# Date, Urgency, Tickets
'07/06/2016', '1', '0'
'07/06/2016', '2', '0'
'07/06/2016', '3', '10'
'07/06/2016', '4', '0'
'07/06/2016', '5', '0'
'08/06/2016', '1', '0'
'08/06/2016', '2', '0'
'08/06/2016', '3', '0'
'08/06/2016', '4', '0'
'08/06/2016', '5', '0'
...
'14/06/2016', '1', '1'
'14/06/2016', '2', '0'
'14/06/2016', '3', '0'
'14/06/2016', '4', '0'
'14/06/2016', '5', '1'
And so on.
I am kind of getting the hang of SQL (self teaching) so all and any help is much appreciated.
EDIT: Schema added, I think this is what you was asking for (hope it works) http://sqlfiddle.com/#!9/715c7
Your query produces one row per urgency because you only group by that column. In order to see distinct results for each date and urgency you must modify your GROUP BY.
SELECT
DATE_FORMAT(date,'%d/%m/%Y') AS Date,
Urgency,
COUNT(*) as Tickets
FROM
glpi.glpi_tickets
WHERE
month(date)=month(NOW())
GROUP BY
DATE(date),
urgency
ORDER BY
date, urgency ASC;
I think this is what you are looking for. Though I did not have the schema, I tried to write the query. I think this is what you are looking for. (Please check the SQL, I have edited. It should generate a report like how you want, only missing records are, if there is no data for a date.)
select DATE_FORMAT(dummy.date,'%d/%m/%Y') Date, dummy.Urgency, ifnull(main.Tickets, 0) Tickets from
(select * from
(select distinct date(date) date from glpi_tickets
WHERE month(date)=month(NOW()) ) dates
cross join
(select distinct Urgency from glpi_tickets) urgency
order by Date, Urgency) dummy
left join
(SELECT date(date) date, Urgency, COUNT(*) as Tickets
FROM glpi_tickets
WHERE month(date)=month(NOW())
GROUP BY date(date), Urgency
ORDER BY date(date), Urgency) main
on dummy.date = main.date
and dummy.Urgency = main.Urgency
order by dummy.date asc, Urgency asc
I guess the below SQL will serve your purpose, I took a little help from here. You need to optimize the query for big data.
select DATE_FORMAT(dummy.date,'%d/%m/%Y') Date, dummy.Urgency, ifnull(main.Tickets, 0) Tickets from
(select * from
(SELECT date_field date
FROM
(SELECT
MAKEDATE(YEAR(NOW()),1) +
INTERVAL (MONTH(NOW())-1) MONTH +
INTERVAL daynum DAY date_field
FROM
(SELECT t*10+u daynum
FROM
(SELECT 0 t UNION SELECT 1 UNION SELECT 2 UNION SELECT 3) A,
(SELECT 0 u UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
UNION SELECT 8 UNION SELECT 9) B
ORDER BY daynum
) AA
) AAA
WHERE MONTH(date_field) = MONTH(NOW())
and date_field >= (select min(date(date)) from glpi_tickets WHERE month(date)=month(NOW()))
and date_field <= (select max(date(date)) from glpi_tickets WHERE month(date)=month(NOW())) ) dates
cross join
(select distinct Urgency from glpi_tickets) urgency
order by date, Urgency) dummy
left join
(SELECT date(date) date, Urgency, COUNT(*) as Tickets
FROM glpi_tickets
WHERE month(date)=month(NOW())
GROUP BY date(date), Urgency
ORDER BY date(date), Urgency) main
on dummy.date = main.date
and dummy.Urgency = main.Urgency
order by dummy.date asc, Urgency asc
So this is what I ended up doing and it appears to be supplying the data just how I want it.
First of all I created a new table to store the data in:
CREATE TABLE glpi_plugin_ns_ticketstats
(
id INT(11),
daterun date,
timerun time,
totaltickets INT(11),
verylow INT(11),
low INT(11),
med INT(11),
high INT(11),
veryhigh INT(11));
Then I built a stored procedure to collect and populate the data:
USE `glpi`;
DROP procedure IF EXISTS `Daily_Ticket_Stats`;
DELIMITER $$
USE `glpi`$$
CREATE DEFINER=`root`#`localhost` PROCEDURE `Daily_Ticket_Stats`()
BEGIN
declare todayd date;
## Declaring the variable for the daterun column ##
declare todayt time;
## Declaring the variable for the timerun column ##
declare totalt int(11);
## Declaring the variable for totaltickets column ##
declare vlow int (11);
## Declaring the variable for verylow column ##
declare low int(11);
## Declaring the variable for low column ##
declare med int(11);
## Declaring the variable for med column ##
declare high int (11);
## Declaring the variable for high column ##
declare vhigh int(11);
## Declaring the variable for veryhigh column ##
set todayd = CURDATE();
## Set date to today ##
set todayt = CURTIME();
## Set time to now ##
set totalt = (SELECT COUNT(*) as ttickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW()));
## This has set the total for the total tickets variable ##
set vlow = (SELECT COUNT(*) as vltickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW())
AND urgency = '1');
## This has set the total for the very low urgency tickets variable ##
set low = (SELECT COUNT(*) as ltickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW())
AND urgency = '2');
## This has set the total for the low urgency tickets variable ##
set med = (SELECT COUNT(*) as mtickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW())
AND urgency = '3');
## This has set the total for the medium urgency tickets variable ##
set high = (SELECT COUNT(*) as htickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW())
AND urgency = '4');
## This has set the total for the high urgency tickets variable ##
set vhigh = (SELECT COUNT(*) as vhtickets
FROM glpi.glpi_tickets
WHERE day(date)=day(NOW())
AND urgency = '5');
IF EXISTS(
SELECT *
FROM glpi.glpi_plugin_ns_ticketstats
WHERE daterun = CURDATE())
THEN
BEGIN
UPDATE glpi.glpi_plugin_ns_ticketstats
SET
timerun = CURTIME(),
totaltickets = totalt,
verylow = vlow,
low = low,
med = med,
high = high,
veryhigh = vhigh
WHERE
daterun = CURDATE();
END;
ELSE
INSERT INTO glpi.glpi_plugin_ns_ticketstats VALUES (NULL,todayd,todayt,totalt,vlow,low,med,high,vhigh);
END IF;
END
#$$
DELIMITER ;
I then set this procedure to run every hour so the stats are recent if my manager wishes to refer to them during the day (I entered this directly onto the mysql server terminal):
CREATE EVENT TicketStatusUpdate
ON SCHEDULE EVERY 1 HOUR
STARTS CURRENT_TIMESTAMP + INTERVAL 29 MINUTE
DO
CALL Daily_Ticket_Stats();
The 29 minute is because I wanted it to run as close to the hour as I could get it.
This now outputs lovely data in a format that allows me to create a stacked graph in Excel (Spoofed entries from 1st-16th June so I had entries from start of month):
# id, daterun, timerun, totaltickets, verylow, low, med, high, veryhigh
'1', '2016-06-01', '23:00:00', '0', '0', '0', '0', '0', '0'
'2', '2016-06-02', '23:00:00', '0', '0', '0', '0', '0', '0'
'3', '2016-06-03', '23:00:00', '0', '0', '0', '0', '0', '0'
'4', '2016-06-04', '23:00:00', '0', '0', '0', '0', '0', '0'
'5', '2016-06-05', '23:00:00', '0', '0', '0', '0', '0', '0'
'6', '2016-06-06', '23:00:00', '0', '0', '0', '0', '0', '0'
'7', '2016-06-07', '23:00:00', '0', '0', '0', '0', '0', '0'
'8', '2016-06-08', '23:00:00', '0', '0', '0', '0', '0', '0'
'9', '2016-06-09', '23:00:00', '0', '0', '0', '0', '0', '0'
'10', '2016-06-10', '23:00:00', '0', '0', '0', '0', '0', '0'
'11', '2016-06-11', '23:00:00', '0', '0', '0', '0', '0', '0'
'12', '2016-06-12', '23:00:00', '0', '0', '0', '0', '0', '0'
'13', '2016-06-13', '23:00:00', '0', '0', '0', '0', '0', '0'
'14', '2016-06-14', '23:00:00', '0', '0', '0', '0', '0', '0'
'15', '2016-06-15', '23:00:00', '0', '0', '0', '0', '0', '0'
'16', '2016-06-16', '23:00:00', '0', '0', '0', '0', '0', '0'
'17', '2016-06-17', '12:31:22', '4', '1', '0', '0', '0', '3'
This then lets me do a select so I only get the current month imported into Excel:
select * from glpi.glpi_plugin_ns_ticketstats
where month(daterun)=month(NOW())
I'll leave this here so if anyone wants to use it they can, thanks everyone for your time and help :)
iFr4g

Mysql compare sum of columns to columns in another table

How can I select a row from another table based on the sum of column from the left table
SELECT Group_concat(c.cartid SEPARATOR ',') AS CartIDs,
Sum(c.grandtotal) AS Sum,
r.percentage
FROM carts c
LEFT JOIN rebates r
ON Sum(c.grandtotal) >= r.fromamountpurchased
AND Sum(c.grandtotal) <= r.toamountpurchased
WHERE c.ispaid = '1'
AND c.addedtorebates = '0'
GROUP BY c.customerid
But this doesn't work. I also tried HAVING also doesn't work.
Is it possible in one query?
Thanks!
UPDATE:
CREATE TABLE IF NOT EXISTS `carts` (
`CartID` bigint(20) NOT NULL AUTO_INCREMENT,
`CustomerID` bigint(20) NOT NULL,
`GrandTotal` decimal(10,2) NOT NULL,
`IsPaid` enum('0','1','2') NOT NULL,
`AddedToRebates` enum('0','1') NOT NULL,
PRIMARY KEY (`CartID`)
)
INSERT INTO `carts` (`CartID`, `CustomerID`, `GrandTotal`, `IsPaid`,
`AddedToRebates`, ) VALUES
(71, 28, '57450.00', '1', '0' ),
(73, 28, '57450.00', '1', '0');
CREATE TABLE IF NOT EXISTS `rebates` (
`RebateID` bigint(20) NOT NULL AUTO_INCREMENT,
`Percentage` varchar(255) NOT NULL COMMENT 'in %',
`FromAmountPurchased` decimal(10,2) NOT NULL,
`ToAmountPurchased` decimal(10,2) NOT NULL,
`CashEquivalent` decimal(10,2) NOT NULL,
PRIMARY KEY (`RebateID`)
)
INSERT INTO `rebates` (`RebateID`, `Percentage`, `FromAmountPurchased`,
`ToAmountPurchased`, `CashEquivalent`) VALUES
(1, '5', '50000.00', '69999.00', '3000.00'),
(2, '10', '70000.00', '79999.00', '5000.00'),
(3, '15', '80000.00', '89999.00', '6000.00'),
(4, '20', '90000.00', '99999.00', '7000.00'),
(5, '25', '100000.00', '150000.00', '8000.00'),
(6, '0', '0.00', '49999.00', '0.00');
Try this:
select q1.CartIDs, q1.total, r.percentage
from
(select group_concat(c.cartid) as CartIDs, sum(c.grandtotal) as total
from carts c
where c.ispaid = '1'
and c.addedtorebates = '0'
group by c.customerid ) q1
left join rebates r
on q1.total >= r.fromamountpurchased
and q1.total <= r.toamountpurchased
Here is a demo fiddle for you: http://sqlfiddle.com/#!9/d27f5/3
You cannot use aggregate functions like SUM() in the join predicate, so in this instance, a subquery is useful
You can achieve your result with a sub query. Please note that this sub query requires an additional scan of carts.
SELECT GROUP_CONCAT(c.CartID SEPARATOR ',') AS CartIDs, SUM(c.GrandTotal) as Sum, r.Percentage
FROM carts c
INNER JOIN (
SELECT SUM(GrandTotal) as grandTotal, CustomerID
FROM carts
GROUP BY CustomerID
) cSums ON cSums.CustomerID = c.CustomerID
LEFT JOIN rebates r ON cSums.grandTotal >= r.FromAmountPurchased AND cSums.grandTotal <= r.ToAmountPurchased
WHERE c.IsPaid = '1' AND c.AddedToRebates = '0' GROUP BY c.CustomerID