MYSQL Query works for current week not next - mysql

SELECT a.agent, a.talktime, a.percentclosed,COALESCE(COUNT(b.dealamount),0),COALESCE(SUM(b.dealamount),0) , b.dealdate
FROM closers a
LEFT JOIN deals b ON a.agent = b.agent
WHERE b.dealdate IS NULL OR YEARWEEK( b.dealdate ) = YEARWEEK( NOW( ) )
GROUP BY a.agent
ORDER BY COALESCE( SUM( b.dealamount ) , 0 ) DESC
Can anybody help me fix this query i know its messy but im new to this,
This works fine for the current week but if i add +1 to simulate a future week everybody who has a deal the week before does not show,
Thanks,
John,
IMAGE OF QUERY'S

WEEKOFYEAR is not good in this case because it will wrap at year's end. You should use YEARWEEK().
WHERE b.dealdate IS NULL OR YEARWEEK( b.dealdate ) = YEARWEEK( NOW( ) ) +1

Got it to work!,
SELECT a.agent, a.talktime, a.percentclosed, COALESCE( COUNT( b.dealamount ) , 0 ) ,COALESCE( SUM( b.dealamount ) , 0 ) , b.dealdate
FROM closers a
LEFT JOIN deals b ON a.agent = b.agent
AND WEEKOFYEAR( b.dealdate ) = WEEKOFYEAR( NOW( ) )
WHERE b.dealdate IS NULL
OR WEEKOFYEAR( b.dealdate ) = WEEKOFYEAR( NOW( ) )
GROUP BY a.agent
ORDER BY COALESCE( SUM( b.dealamount ) , 0 ) DESC
LIMIT 0 , 30

WHERE b.dealdate IS NULL OR WEEKOFYEAR( b.dealdate ) = WEEKOFYEAR( date_add(NOW( ), interval 1 week))
use the interval feature of mysql, and the date_add or date_sub function
Reference

Related

What kind of query optimization can be done on this query?

I'm listing out orders data based on this query. This query basically pulls the recurring orders data from the table. I'm also using some dropdown and a input field to search / filter query results.
SELECT
orders.id,
parent_id,
(
SELECT
COUNT(*)
FROM
orders o
WHERE
o.parent_id = orders.id
) AS recurring_order_count,
shopify_order_type,
shopify_order_id,
shopify_order_customer_ID,
coupon_code AS coupon,
FORMAT(shopify_order_total_price, 2) AS shopify_order_total_price,
FORMAT(
shopify_order_subtotal_price,
2
) AS shopify_order_subtotal_price,
FORMAT(
shopify_order_total_line_items_price,
2
) AS shopify_order_total_line_items_price,
FORMAT(commission_amount, 2) AS commission_amount,
(
CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected'
END
) AS is_paid,
(
CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated'
END
) AS is_invoice_generated,
DATE_FORMAT(
shopify_order_created_at,
'%m-%d-%Y'
) AS shopify_order_created_at,
(
CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused'
END
) AS is_paused,
DATE_FORMAT(
shopify_recurring_date,
'%m-%d-%Y'
) AS shopify_recurring_date
FROM
`orders`
WHERE
coupon_code LIKE '%GERALD8314%' OR shopify_order_id LIKE '%GERALD8314%' OR(
CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected'
END
) LIKE '%GERALD8314%' OR(
CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated'
END
) LIKE '%GERALD8314%' OR DATE_FORMAT(
shopify_order_created_at,
'%m-%d-%Y'
) LIKE '%GERALD8314%' OR(
CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused'
END
) LIKE '%GERALD8314%' OR DATE_FORMAT(
shopify_recurring_date,
'%m-%d-%Y'
) LIKE '%GERALD8314%' AND DATE_FORMAT(
shopify_order_created_at,
'%Y-%m-%d'
) BETWEEN ? AND ?
GROUP BY
`id`
HAVING
parent_id = 0 AND shopify_order_type = 1
ORDER BY
`id`
DESC
LIMIT 10 OFFSET 0
Is this query optimized? Is this SELECT COUNT(*) FROM orders WHERE o.parent_id = orders.id AS recurring_order_count line most expensive in terms of query execution speed? Is there anything I should take care to improve the query speed here? Please advise.
OR and LIKE with leading wildcard are terrible for performance. Consider having a FULLTEXT index across the relevant columns. If it is practical, it will be immensely faster.
WHERE coupon_code LIKE '%GERALD8314%'
OR shopify_order_id LIKE '%GERALD8314%' OR( CASE WHEN is_paid = 0 THEN 'No' WHEN is_paid = 1 THEN 'Yes' ELSE 'Rejected' END ) LIKE '%GERALD8314%' OR( CASE WHEN is_invoice_generated = 1 THEN 'Pending' ELSE 'Invoice Generated' END ) LIKE '%GERALD8314%'
OR DATE_FORMAT( shopify_order_created_at, '%m-%d-%Y' ) LIKE '%GERALD8314%' OR( CASE WHEN is_paused = 0 THEN 'Running' ELSE 'Paused' END ) LIKE '%GERALD8314%'
OR DATE_FORMAT( shopify_recurring_date, '%m-%d-%Y' ) LIKE '%GERALD8314%'
AND DATE_FORMAT( shopify_order_created_at, '%Y-%m-%d' ) BETWEEN ? AND ?
Also, there may be surprises in the results. Note that you have
a OR b OR c AND d
which is the same as
a OR b OR (c AND d)
I suspect you wanted
(a OR b OR c) AND d
I think the GROUP BY is unnecessary. And the HAVING clauses can be merged into the WHERE.
GROUP BY `id`
HAVING parent_id = 0
AND shopify_order_type = 1
ORDER BY `id` DESC
This has multiple issues:
DATE_FORMAT( shopify_order_created_at, '%Y-%m-%d' ) BETWEEN ? AND ?
BETWEEN is "inclusive". The way you have written the query, it will include the entire ending day. This may not be what you wanted.
Assuming the variable is a DATE or DATETIME, it can be simplified to
shopify_order_created_at BETWEEN ? AND ?
There may be more tips; fix these then come back for more.

How can I compute the average of a nested SQL statement?

I have this crazy nested sql statement and it returns something like this:
However, what I want is to use this data in the image to return 2 columns. col_1:SUM(avgWithCriteria)/43 and col_2:SUM(avgWithoutCriteria)/43. How can I do this by adding onto my query below?
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a;
Try this:-
SELECT percentDifference,avgWithCriteria,avgWithoutCriteria,totalAverage,neighbourhood_cleansed,
(col1_1/43) as col1,(col2_2/43) as col2
from
(
SELECT a.*,SUM(avgWithCriteria) as col1_1,SUM(avgWithoutCriteria) as col2_2
FROM
(
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a
) a
GROUP BY percentDifference,avgWithCriteria,avgWithoutCriteria,totalAverage,neighbourhood_cleansed
) a;
SELECT
( ( avgWithCriteria - totalAverage ) / ( ( avgWithCriteria + totalAverage ) / 2 ) ) * 100 as percentDifference,
SUM(avgWithCriteria)/43 AS col_1,
SUM(avgWithoutCriteria)/43 AS col_2,
a.*
FROM
(SELECT
AVG( CASE WHEN 'f' not in ( has_free_parking ) THEN price ELSE null END) as avgWithCriteria,
AVG( CASE WHEN 'f' in ( has_free_parking ) THEN price ELSE null END) as avgWithoutCriteria,
AVG( price ) as totalAverage,
neighbourhood_cleansed
FROM listings
WHERE city_name="berlin"
AND price <= 1000000
AND price >= -1
AND reviews_per_month <= 1000000
AND reviews_per_month >= -1
AND est_monthly_income <= 1000000
AND est_monthly_income >= -1
GROUP BY neighbourhood_cleansed ) a;

MySQL IN Condition Subquery

I have a question and answers listing and an option to filter the questions based on the % of correct answers. So I am using the following query for the listing :
SELECT
question_id,
text
FROM
test_answers LEFT JOIN test_questions ON test_questions.id = test_answers.question_id
LEFT JOIN test_categories ON test_questions.`category_id` = test_categories.id
WHERE `question_id` IN(question IDS)
GROUP BY `question_id`
ORDER BY `question_id` DESC;
and using another query for finding the question IDS for which the % of correct answers in the given range. The query is as follows :
SELECT q1.question_id FROM (
SELECT test_answers.question_id AS question_id,
SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) AS correct_answers,
SUM( IF( test_answers.correct_answer !=1, 1, 0 ) ) AS incorrect_answers,
round( ( SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) / ( SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) + SUM( IF( test_answers.correct_answer !=1, 1, 0 ) ) ) *100 ) , 2 ) AS percentage
FROM test_replies
JOIN test_answers ON test_replies.answer_id = test_answers.id
GROUP BY test_answers.question_id
HAVING percentage between 80 and 89 AND correct_answers >25
) AS q1
Now the issue is that the second query returns almost 4000 question Ids and it will increase in the near future and might be become 10k or more. So I seriously would like to optimize the query as it is going to impact the performance in a great deal. Can anyone suggest a better method for doing it ?
try join instead of IN, see if it helps. (sql not tested)
SELECT
ta.question_id, text
FROM
(
SELECT test_answers.question_id AS question_id,
SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) AS correct_answers,
SUM( IF( test_answers.correct_answer !=1, 1, 0 ) ) AS incorrect_answers,
round( ( SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) / ( SUM( IF( test_answers.correct_answer =1, 1, 0 ) ) + SUM( IF( test_answers.correct_answer !=1, 1, 0 ) ) ) *100 ) , 2 ) AS percentage
FROM test_replies
JOIN test_answers ON test_replies.answer_id = test_answers.id
GROUP BY test_answers.question_id
HAVING percentage between 80 and 89 AND correct_answers >25
) AS q1
INNER JOIN
test_answers ta USING (question_id)
LEFT JOIN
test_questions ON test_questions.id = ta.question_id
LEFT JOIN
test_categories ON test_questions.`category_id` = test_categories.id
GROUP BY
ta.question_id`
ORDER BY
ta.question_id DESC;

MySQL query take more time to execution

SELECT
gst_journal.*,
salesmain.TransactionNo
FROM
`gst_journal`
LEFT JOIN salesmain
ON (
gst_journal.docNo = salesmain.InvoiceNo
AND gst_journal.Source = salesmain.Source
)
WHERE (
MONTH(salesmain.TDate) = '10'
AND YEAR(salesmain.TDate) = '2013'
AND salesmain.TDate BETWEEN STR_TO_DATE('2013-10-01', '%Y-%m-%d')
AND STR_TO_DATE('2013-10-31', '%Y-%m-%d')
AND (
(
gst_journal.inOutTax = 'OUT'
AND gst_journal.taxType IN ('SR', 'GST')
AND gst_journal.Source IN ('AR', 'NR', 'BR', 'PR', 'JV', 'CR')
)
)
)
OR (
MONTH(gst_journal.TDate) = '10'
AND YEAR(gst_journal.TDate) = '2013'
AND (
gst_journal.TDate BETWEEN STR_TO_DATE('2013-10-01', '%Y-%m-%d')
AND STR_TO_DATE('2013-10-31', '%Y-%m-%d')
AND (
gst_journal.taxType = 'SR'
AND gst_journal.Source IN ('BR')
)
)
)
ORDER BY gst_journal.Tdate,
salesmain.TDate ;
this query run properly and records give correct but it take to time run.
Any one help to optimize time query.
Thanks

Multiple sum in SQL query

SELECT sum( plot_status = 'OPEN' ) AS OPEN
, sum( plot_status = 'SOLD' ) AS SOLD
FROM `tbl_plot`
GROUP BY `plot_status
This is giving
OPEN SOLD
7 0
0 8
How to make it
OPEN SOLD
7 8
Or is it possible?
just remove the GROUP BY clause and it will work.
SELECT sum( plot_status = 'OPEN' ) AS `OPEN` ,
sum( plot_status = 'SOLD' ) AS SOLD
FROM `tbl_plot`
If there is present plot_name or id then group by that not by plot_status:
SELECT sum( plot_status = 'OPEN' ) AS
OPEN , sum( plot_status = 'SOLD' ) AS SOLD
FROM `tbl_plot`
GROUP BY //`plot_name or plot_id
This will work for you for individual plot.
And if you don't want that then remove the group by clause.
select * from
(
select sum( plot_status = 'OPEN' FROM tbl_plot ) AS OPEN
select sum( plot_status = 'SOLD' FROM tbl_plot ) As Sold
)tbl