I would like your help with the following:
query 1:
SELECT stock.ST_CODE as xCODE, (sum(ordercont.QTY) / 12) as x12WeeksAvg
FROM orders
LEFT JOIN ordercont ON ordercont.O_REF = orders.O_REF
LEFT JOIN stock ON stock.PD_CODE = ordercont.PD_CODE
WHERE stock.ST_CODE IS NOT NULL
AND orders.O_CUSTDATE BETWEEN DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 84 DAY)
AND DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY stock.ST_CODE
query 2:
SELECT stock.ST_CODE as xCODE, (sum(ordercont.QTY) / 4) as x4WeeksAvg
FROM orders LEFT JOIN ordercont ON ordercont.O_REF = orders.O_REF
LEFT JOIN stock ON stock.PD_CODE = ordercont.PD_CODE
WHERE stock.ST_CODE IS NOT NULL
AND orders.O_CUSTDATE BETWEEN DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 28 DAY)
AND DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY stock.ST_CODE
Is there any way to have the result like this (the queries returns different number of results):
------------------------------------
| xCode | x12WeeksAvg | x4WeeksAvg |
------------------------------------
| ... | ... | ... |
------------------------------------
Thank you!!
Split the BETWEEN condition
orders.O_CUSTDATE BETWEEN DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 84 DAY)
AND DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
into two parts
AND orders.O_CUSTDATE >= DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 84 DAY)
AND orders.O_CUSTDATE <= DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
and rewrite it to
AND orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 84) DAY
AND orders.O_CUSTDATE <= CURDATE() - INTERVAL (DAYOFWEEK(NOW()) - 1) DAY
to get shorter and more readable code. Do the same for the second query.
Now the two queries differ only in two expressions
(sum(ordercont.QTY) / 12) as x12WeeksAvg
(sum(ordercont.QTY) / 4) as x4WeeksAvg
orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 84) DAY
orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 28) DAY
Given
<X>: orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 84) DAY
and
<Y>: orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 28) DAY
you can use conditional aggregation to combine the two queries:
SELECT stock.ST_CODE as xCODE,
(sum(CASE WHEN <X> THEN ordercont.QTY ELSE 0 END) / 12) as x12WeeksAvg,
(sum(CASE WHEN <Y> THEN ordercont.QTY ELSE 0 END) / 4) as x4WeeksAvg
FROM orders
LEFT JOIN ordercont ON ordercont.O_REF = orders.O_REF
LEFT JOIN stock ON stock.PD_CODE = ordercont.PD_CODE
WHERE stock.ST_CODE IS NOT NULL
AND orders.O_CUSTDATE <= CURDATE() - INTERVAL (DAYOFWEEK(NOW()) - 1) DAY
GROUP BY stock.ST_CODE
Replace <X> and <Y> accordingly.
Update
To improve the performance you can add
AND orders.O_CUSTDATE >= CURDATE() - INTERVAL (WEEKDAY(NOW()) + 84) DAY
to the WHERE clause.
Also note that the condition stock.ST_CODE IS NOT NULL will convert your LEFT JOINs to INNER JOINs. So you could as well just write JOIN.
You can subquery them like this to get your desired output:
SELECT A.xCODE,
COALESCE(B.x12WeeksAvg, 'N/A') as x12WeeksAvg,
COALESCE(C.x4WeeksAvg, 'N/A') as x4WeeksAvg
FROM (SELECT DISTINCT ST_CODE as xCODE FROM stock) A
LEFT JOIN (
SELECT stock.ST_CODE as xCODE, (sum(ordercont.QTY) / 12) as x12WeeksAvg
FROM orders
LEFT JOIN ordercont ON ordercont.O_REF = orders.O_REF
LEFT JOIN stock ON stock.PD_CODE = ordercont.PD_CODE
WHERE stock.ST_CODE IS NOT NULL
AND orders.O_CUSTDATE BETWEEN DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 84 DAY) AND DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY stock.ST_CODE
) B ON A.xCODE = B.xCODE
LEFT JOIN (
SELECT stock.ST_CODE as xCODE, (sum(ordercont.QTY) / 4) as x4WeeksAvg
FROM orders
LEFT JOIN ordercont ON ordercont.O_REF = orders.O_REF
LEFT JOIN stock ON stock.PD_CODE = ordercont.PD_CODE
WHERE stock.ST_CODE IS NOT NULL
AND orders.O_CUSTDATE BETWEEN DATE_SUB( (DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY)) , INTERVAL 28 DAY) AND DATE_SUB(DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-1 DAY)
GROUP BY stock.ST_CODE
) C ON A.xCODE = C.xCODE
WHERE COALESCE(B.x12WeeksAvg, C.x4WeeksAvg) IS NOT NULL
Related
for this my query is =
SELECT SalesDate,COUNT(Shape) as pcs,
ROUND(SUM(TotalAmount),2) as amount,
ROUND(SUM(Carat),2) as carat,
ROUND(ROUND(SUM(TotalAmount),2)/ROUND(SUM(Carat),2),2) as avgprice
from `tbl_sales`
WHERE IF((SalesDate = CURDATE() - INTERVAL 1 DAY) = null, SalesDate=CURDATE() - INTERVAL 2 DAY,SalesDate= CURDATE() - INTERVAL 1 DAY)
so this is my response
so in If condition I want to make sure that if the data in yesterday data is null or 0 then it will take day before yesterday
Perhaps something like this:
SELECT SalesDate,COUNT(Shape) as pcs,
ROUND(SUM(TotalAmount),2) as amount,
ROUND(SUM(Carat),2) as carat,
ROUND(ROUND(SUM(TotalAmount),2)/ROUND(SUM(Carat),2),2) as avgprice
FROM `tbl_sales`
GROUP BY SalesDate
HAVING SalesDate = CASE WHEN (SalesDate = CURDATE() - INTERVAL 1 DAY)=0
THEN CURDATE() - INTERVAL 2 DAY
WHEN (SalesDate = CURDATE() - INTERVAL 1 DAY)=1
AND amount IS NULL
THEN CURDATE() - INTERVAL 2 DAY
ELSE CURDATE() - INTERVAL 1 DAY END;
When you do (SalesDate = CURDATE() - INTERVAL 1 DAY) it will return false=0 and true=1. Therefore doing (SalesDate = CURDATE() - INTERVAL 1 DAY) = NULL, although it should be .. IS NULL instead of .. = NULL.. either way, it won't work. Let's inspect the CASE expression in HAVING part.
If it return 0 means there's no matching with date specified, then take 2 days before:
CASE WHEN (SalesDate = CURDATE() - INTERVAL 1 DAY)=0
THEN CURDATE() - INTERVAL 2 DAY
If it has match for the date checking and return 1 BUT with NULL amount, then take 2 days before as well:
WHEN (SalesDate = CURDATE() - INTERVAL 1 DAY)=1
AND amount IS NULL
THEN CURDATE() - INTERVAL 2 DAY
Else take yesterday date:
ELSE CURDATE() - INTERVAL 1 DAY END;
Demo fiddle
You need to cast your column to date:
SELECT SalesDate,COUNT(Shape) as pcs,
ROUND(SUM(TotalAmount),2) as amount,
ROUND(SUM(Carat),2) as carat,
ROUND(ROUND(SUM(TotalAmount),2)/ROUND(SUM(Carat),2),2) as avgprice
from `tbl_sales`
WHERE IF((CAST(SalesDate AS date) = CURDATE() - INTERVAL 1 DAY), CAST(SalesDate AS date) = CURDATE() - INTERVAL 2 DAY, CAST(SalesDate AS date) = CURDATE() - INTERVAL 1 DAY)
select pd.state AS StateName, pd.county AS `County Name`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 3 MONTH) AS `0-3 Months`,
SUM(`0-3 Months` - INTERVAL 3 MONTH) AS `3-6 Months`
from resnet.property_details pd join
resnet.property_closings pc
on pd.property_id = pc.Property_id
group by pd.state, pd.county;
How can I get the 3 month interval from the previous 3 month interval value? So it will be 3-6 months?
You can use BETWEEN..AND, e.g.:
select pd.state AS StateName, pd.county AS `County Name`,
SUM(pc.close_dt >= CURDATE() - INTERVAL 3 MONTH) AS `0-3 Months`,
SUM(pc.close_dt BETWEEN CURDATE() - INTERVAL 3 MONTH AND CURDATE() - INTERVAL 6 MONTH) AS `3-6 Months`
from resnet.property_details pd join
resnet.property_closings pc
on pd.property_id = pc.Property_id
group by pd.state, pd.county;
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
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
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