MySQL last 7 days being ignored - mysql

I need to get all the Paid and Provisional Entry from the last 7 days but I keep getting everything returned. I am unsure what I am doing wrong I have read through quite a few posts on here and cant fathom what its. MySQL 5.6 if it makes any diffrence to what I have been doing.
SELECT
DATE_FORMAT(FROM_UNIXTIME(ct.entry_date),'%d/%m/%Y') AS booking_date,
cd.field_id_69 AS marriage_date,
cd.field_id_54 AS email_address,
CONCAT(cd.field_id_9, ' ', cd.field_id_10) AS bride_name,
CONCAT(cd.field_id_13, ' ', cd.field_id_14) AS groom_name,
ctco.title AS centre_and_course_date,
(SELECT DATE_FORMAT(FROM_UNIXTIME(col_id_1),'%d/%m/%Y') FROM
exp_channel_grid_field_50 cg WHERE cg.entry_id = ctco.entry_id ORDER BY
cg.row_id DESC LIMIT 1) AS course_end_date,
ct.status AS payment_status
FROM exp_channel_titles ct
JOIN exp_channel_data cd ON cd.entry_id = ct.entry_id
JOIN exp_relationships rco ON rco.parent_id = ct.entry_id AND rco.field_id = 41
JOIN exp_channel_titles ctco ON rco.child_id = ctco.entry_id
WHERE ct.channel_id = 2
AND ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY)
AND ct.status = 'Paid'
AND ct.status = 'Provisional';

There is problem in your WHERE statement
AND ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND ct.status = 'Paid' AND ct.status = 'Provisional';
The BETWEEN keyword needs to be followed by 2 dates, so ct.status = 'Paid' will be converted to DATE which return NULL. Hence your WHERE statement turns into.
AND ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND NULL AND ct.status = 'Provisional';
The result is that your query will return all data that have status = 'Provisional'.
You could try to modify the WHERE statement to
AND ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE() AND ct.status IN ('Paid', 'Provisional');

The syntax of BETWEEN is BETWEEN startdate AND enddate. You wrote:
ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND ct.status = 'Paid'
So it's using DATE_SUB(CURDATE(), INTERVAL 7 DAY) as the starting date, and ct.status = 'Paid' as the ending date. I'm surprised it's matching anything.
Change it to:
ct.entry_date BETWEEN DATE_SUB(CURDATE(), INTERVAL 7 DAY) AND CURDATE()
Or if you don't have any dates in the future, you can simply write:
ct.entry_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)

Related

MYSQL: Trying to count Property_IDs over a close_dt Interval

select
pd.state AS StateName,
pd.county AS `County Name`,
CASE pc.close_dt WHEN pc.close_dt >= DATE(NOW() - INTERVAL 3 MONTH)
THEN COUNT(pd.property_id)
ELSE NULL
END AS `3 MONTH`,
CASE pc.close_dt WHEN pc.close_dt >= DATE(NOW() - INTERVAL 6 MONTH)
THEN COUNT(pd.property_id)
ELSE NULL
END AS `6 MONTH`
from resnet.property_details pd
join resnet.property_closings pc
on pd.property_id = pc.Property_id
GROUP BY pd.state,pd.county
I'm trying to get the interval of 3 months from today, 6 months from today for properties that have been closed.
I want it to look like the this:
You need conditional aggregation. In MySQL, you can do this as:
select pd.state AS StateName, pd.county AS `County Name`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 3 MONTH) AS `3 MONTH`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 6 MONTH) AS `6 MONTH`
from resnet.property_details pd join
resnet.property_closings pc
on pd.property_id = pc.Property_id
group by pd.state, pd.county;
Notes:
Your case syntax just doesn't make sense. You either have conditions (as case when <condition> or you have constants as case <column> when <value>). But not both.
date(now()) = CURDATE().
You don't need case expressions because MySQL treats booleans as integers in a numeric context. You can just "sum them up" to count the number of true values.
EDIT:
If you want 3-6 months, then you would do:
SUM(pc.close_dt >= CURDATE() - INTERVAL 6 MONTH AND
pc.close_dt < CURDATE() - INTERVAL 3 MONTH) AS `6 MONTH`

mysql use a different set of WHERE statements if this=1

I need to do a single select on a table, but if Product='football' I need to do a couple of WHEREs, but if Product='something' then do something else. I am not sure if I need to do an IF statement, or a UNION or a CASE which I have never used.
Example of what I would like to have worked but obviously doesn't
SELECT *
FROM
orders
IF Product = 'Football'{
WHERE
AND RenewalDate < DATE_ADD(CURDATE(), INTERVAL 31 DAY)
AND RenewalDate > DATE_SUB(CURDATE(), INTERVAL 31 DAY)
}ELSE IF Product = 'Something'{
AND RenewalDate < DATE_ADD(CURDATE(), INTERVAL 10 DAY)
AND RenewalDate > DATE_SUB(CURDATE(), INTERVAL 10 DAY)
}
ORDER BY
RenewalDate
Now I know that looks like php but its just to show roughly what I want to happen
No if required. Just boolean logic:
SELECT o.*
FROM orders o
WHERE (Product = 'Football' AND
RenewalDate < DATE_ADD(CURDATE(), INTERVAL 31 DAY)
RenewalDate > DATE_SUB(CURDATE(), INTERVAL 31 DAY)
) OR
(Product = 'Something' AND
RenewalDate < DATE_ADD(CURDATE(), INTERVAL 10 DAY) AND
RenewalDate > DATE_SUB(CURDATE(), INTERVAL 10 DAY)
)
ORDER BY RenewalDate;

MYSQL Birthday Query

So im having troubles with my query, Its select the next three birthdays but say if some one birthday is on the April 12th. As soon as April 1st come along that birthday is no longer displayed.
SELECT `users`.`name`,
Date_format(`users_detail`.`dob_date`, '%d') AS day,
Date_format(`users_detail`.`dob_date`, '%M') AS month
FROM `users_detail`
JOIN `users`
ON `users`.`id` = `users_detail`.`id`
WHERE Date_add(`users_detail`.`dob_date`,
INTERVAL Year( Curdate() )- Year(`users_detail`.`dob_date`) + IF(
Dayofyear(
Curdate() ) >= Dayofyear(`users_detail`.`dob_date`), 1, 0 ) year)
BETWEEN Curdate() AND Date_add(Curdate(), INTERVAL 11 month)
ORDER BY `users_detail`.`dob_date` ASC
LIMIT 3
Can you try this ?
SELECT `users`.`name`
FROM `users_detail`
WHERE DATE_ADD(`users_detail`.`dob_date`,
INTERVAL YEAR(CURDATE())-YEAR(`users_detail`.`dob_date`)
+ IF(DAYOFYEAR(CURDATE()) > DAYOFYEAR(`users_detail`.`dob_date`),1,0)
YEAR)
BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL 11 month)
ORDER BY `users_detail`.`dob_date` ASC
LIMIT 3

mysql join same table different result set

I would like to combine different results from the same table as one big result.
SELECT host_name,stats_avgcpu,stats_avgmem,stats_avgswap,stats_avgiowait
FROM sar_stats,sar_hosts,sar_appgroups,sar_environments
WHERE stats_host = host_id
AND host_environment = env_id
AND env_name = 'Staging 2'
AND host_appgroup = group_id
AND group_name = 'Pervasive'
AND DATE(stats_report_time) = DATE_SUB(curdate(), INTERVAL 1 DAY)
SELECT AVG(stats_avgcpu),AVG(stats_avgmem),AVG(stats_avgswap),AVG(stats_avgiowait)
FROM sar_stats
WHERE stats_id = "stat_id of the first query" and DATE(stats_report_time)
BETWEEN DATE_SUB(curdate(), INTERVAL 8 DAY) and DATE_SUB(curdate(), INTERVAL 1 DAY)
SELECT AVG(stats_avgcpu),AVG(stats_avgmem),AVG(stats_avgswap),AVG(stats_avgiowait)
FROM sar_stats
WHERE stats_id = "stat_id of the first query" and DATE(stats_report_time)
BETWEEN DATE_SUB(curdate(), INTERVAL 31 DAY) and DATE_SUB(curdate(), INTERVAL 1 DAY)
Desired output would be something like ...
host_name|stats_avgcpu|stats_avgmem|stats_avgswap|stats_avgiowait|7daycpuavg|7daymemavg|7dayswapavg|7dayiowaitavg|30daycpuavg|30daymemavg|....etc
SQL Fiddle
http://sqlfiddle.com/#!8/4930b/3
It seems like this is what you want. I updated the first query to use proper ANSI JOIN syntax and then for the additional two queries they were joined via a LEFT JOIN on the stats_host field:
SELECT s.stats_host,
h.host_name,
s.stats_avgcpu,
s.stats_avgmem,
s.stats_avgswap,
s.stats_avgiowait,
s7.7dayavgcpu,
s7.7dayavgmem,
s7.7dayavgswap,
s7.7dayavgiowait,
s30.30dayavgcpu,
s30.30dayavgmem,
s30.30dayavgswap,
s30.30dayavgiowait
FROM sar_stats s
INNER JOIN sar_hosts h
on s.stats_host = h.host_id
INNER JOIN sar_appgroups a
on h.host_appgroup = a.group_id
and a.group_name = 'Pervasive'
INNER JOIN sar_environments e
on h.host_environment = e.env_id
and e.env_name = 'Staging 2'
LEFT JOIN
(
SELECT s.stats_host,
AVG(s.stats_avgcpu) AS '7dayavgcpu',
AVG(s.stats_avgmem) AS '7dayavgmem',
AVG(s.stats_avgswap) AS '7dayavgswap',
AVG(s.stats_avgiowait) AS '7dayavgiowait'
FROM sar_stats s
WHERE DATE(stats_report_time) BETWEEN DATE_SUB(curdate(), INTERVAL 8 DAY) AND DATE_SUB(curdate(), INTERVAL 1 DAY)
GROUP BY s.stats_host
) s7
on s.stats_host = s7.stats_host
LEFT JOIN
(
SELECT s.stats_host,
AVG(s.stats_avgcpu) AS '30dayavgcpu',
AVG(s.stats_avgmem) AS '30dayavgmem',
AVG(s.stats_avgswap) AS '30dayavgswap',
AVG(s.stats_avgiowait) AS '30dayavgiowait'
FROM sar_stats s
WHERE DATE(s.stats_report_time) BETWEEN DATE_SUB(curdate(), INTERVAL 31 DAY) AND DATE_SUB(curdate(), INTERVAL 1 DAY)
GROUP BY s.stats_host
) s30
on s.stats_host = s30.stats_host
WHERE DATE(s.stats_report_time) = DATE_SUB(curdate(), INTERVAL 1 DAY);
see SQL Fiddle with Demo

SQL NOT IN Query

Can anyone help me with this MySQL query?
SELECT p.ProductID,
p.StoreID,
p.DiscountPercentage
FROM Products p
WHERE p.IsSpecial = 1
AND p.SpecialDate >= date_sub(now(),interval 15 minute)
AND p.DiscountPercentage >= ?DiscountPercentage
AND p.ProductID NOT IN (SELECT lf.LiveFeedID
From LiveFeed lf
WHERE p.ProductID = lf.ProductID
AND lf.DateAdded >= date_sub(now(),interval 30 day))
AND p.StoreID NOT IN (SELECT lf.LiveFeedID
From LiveFeed lf
WHERE p.StoreID = lf.StoreID
AND lf.DateAdded >= date_sub(now(),interval 6 hour))
ORDER BY p.StoreID, p.DiscountPercentage DESC
I'm trying join where the ProductID is not in the livefeed table in the last 30 days and where the storeid is not in the livefeed table in the last 6 hours, but it does not seem to be working. Any idea what I'm doing wrong?
At a glance, it would appear that your first subquery should be selecting ProductID, not LiveFeedID and your second subquery should be selecting StoreID not LiveFeedID
I'm too late:
SELECT p.ProductID,
p.StoreID,
p.DiscountPercentage
FROM Products p
WHERE p.IsSpecial = 1
AND p.SpecialDate >= date_sub(now(),interval 15 minute)
AND p.DiscountPercentage >= ?DiscountPercentage
AND p.ProductID NOT IN (SELECT lf.productid
FROM LIVEFEED lf
WHERE lf.DateAdded >= DATE_SUB(NOW(), INTERVAL 30 DAY))
AND p.storeid NOT IN (SELECT lf.storeid
FROM LIVEFEED lf
WHERE lf.DateAdded >= DATE_SUB(NOW(), INTERVAL 6 HOUR))
ORDER BY p.StoreID, p.DiscountPercentage DESC
You were using EXISTS syntax with a correllated subquery...
I'm trying to get the top discount for each store.
In that case, use:
SELECT p.StoreID,
MAX(p.DiscountPercentage)
FROM Products p
WHERE p.IsSpecial = 1
AND p.SpecialDate >= date_sub(now(),interval 15 minute)
AND p.DiscountPercentage >= ?DiscountPercentage
AND p.ProductID NOT IN (SELECT lf.productid
FROM LIVEFEED lf
WHERE lf.DateAdded >= DATE_SUB(NOW(), INTERVAL 30 DAY))
AND p.storeid NOT IN (SELECT lf.storeid
FROM LIVEFEED lf
WHERE lf.DateAdded >= DATE_SUB(NOW(), INTERVAL 6 HOUR))
GROUP BY p.storeid
ORDER BY p.StoreID, p.DiscountPercentage DESC