Combining multiple queries of single view in one query - mysql

I am struggling with multiple queries to combine in one query, all these are retrieving from single view for a same date range for all queries i.e.
SELECT business_id_fk,business_name,
IFNULL(count(orderid_customer),0) AS total,
IFNULL(sum(CASE WHEN order_status IN ('CRD') THEN 1 ELSE 0 END), 0) AS crude,
IFNULL(sum(CASE WHEN order_status IN ('UNA') THEN 1 ELSE 0 END), 0) AS unassigned,
IFNULL(sum(CASE WHEN order_status IN ('DEL' , 'MCP' , 'CMP') THEN 1 ELSE 0 END), 0) AS delivered,
IFNULL(sum(CASE WHEN order_status IN ('CNL') THEN 1 ELSE 0 END), 0) AS cancelled,
IFNULL(sum(CASE WHEN order_status IN ( 'CAP' , 'CAD' , 'RSP' , 'RSD') THEN 1 ELSE 0 END), 0) AS postponed
FROM view_orders where order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59' and parent_id IS NULL
AND business_id_fk is not null GROUP BY business_id_fk ORDER BY total DESC;
The above query is to get business wise count
SELECT business_id_fk,business_name,
IFNULL(count(orderid_customer),0) AS total,
IFNULL(sum(CASE WHEN order_status IN ('CRD') THEN 1 ELSE 0 END), 0) AS crude,
IFNULL(sum(CASE WHEN order_status IN ('UNA') THEN 1 ELSE 0 END), 0) AS unassigned,
IFNULL(sum(CASE WHEN order_status IN ('DEL' , 'MCP' , 'CMP') THEN 1 ELSE 0 END), 0) AS delivered,
IFNULL(sum(CASE WHEN order_status IN ('CNL') THEN 1 ELSE 0 END), 0) AS cancelled,
IFNULL(sum(CASE WHEN order_status IN ( 'CAP' , 'CAD' , 'RSP' , 'RSD') THEN 1 ELSE 0 END), 0) AS postponed,
IFNULL(SUM(total), 0) AS 'Estimated_Revenue',
IFNULL(SUM(CASE WHEN order_status IN ('DEL' , 'MCP', 'CMP') THEN total ELSE 0 END), 0) AS 'Generated_Revenue'
FROM view_orders
WHERE order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59'
AND parent_id IS NULL
AND business_id_fk is null
ORDER BY total DESC;
This is to get the count of business_id_fk having null values
select ((SELECT ifnull(count(*),0) as 'total' FROM view_orders where (sla_del_datetime > delivery_datetime) and order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59' and parent_id is null group by business_id_fk) / (SELECT ifnull(count(*),0) as 'total' FROM view_orders where order_status in('DEL','MCP','CMP') order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59' and and parent_id is null group by business_id_fk)*100) as 'sla_adherence';
This query is to get sla_adherence of each business wise and non business
select ((SELECT ifnull(count(*),0) as 'total' FROM view_orders where order_status in('DEL','MCP','CMP') order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59' and and parent_id is null group by business_id_fk) / (SELECT ifnull(count(*),0) as 'total' FROM view_orders where order_datetime between '2017-10-01 00:00:00' and '2017-10-05 23:59:59' and parent_id is null group by business_id_fk)*100) as 'strike_rate';
This query is to get strike_rate of each business wise and non business
I want the result like
business_id_fk||business_name||total||crude||unassigned||delivered||cancelled||postponed||Estimated_Revenue||Generated_Revenue||sla_adherence||strike_rate
1||abc||10||1||..|..|..|..|..|..|..|..|..|x.xx|x.xx
.
.
.
null(non business)||null||..|..|. . . . . . |x.xx|x.xx
each business wise rows for all the above fields and for non business.
Thank you in advance.

One first query is multi-row, the second seems to be a single value. So if those assumptions are right you could try a cross join:
SELECT
business_id_fk
, business_name
, IFNULL(count(orderid_customer),0) AS total
, IFNULL(sum(CASE WHEN order_status IN ('CRD') THEN 1 ELSE 0 END), 0) AS crude
, IFNULL(sum(CASE WHEN order_status IN ('UNA') THEN 1 ELSE 0 END), 0) AS unassigned
, IFNULL(sum(CASE WHEN order_status IN ('DEL' , 'MCP' , 'CMP') THEN 1 ELSE 0 END), 0) AS delivered
, IFNULL(sum(CASE WHEN order_status IN ('CNL') THEN 1 ELSE 0 END), 0) AS cancelled
, IFNULL(sum(CASE WHEN order_status IN ( 'CAP' , 'CAD' , 'RSP' , 'RSD') THEN 1 ELSE 0 END), 0) AS postponed
, cj.sla_adherence
FROM view_orders
CROSS JOIN (
SELECT (
(SELECT ifnull(count(*),0) FROM view_orders where (sla_del_datetime > delivery_datetime) and parent_id is null )
/
(SELECT ifnull(count(*),0) FROM view_orders where order_status in('DEL','MCP','CMP') and parent_id is null )*100.0
) as 'sla_adherence'
) cj
WHERE order_datetime between '2017-08-01 00:00:00' and '2017-10-01 23:59:59'
GROUP BY business_id_fk, business_name, cj.sla_adherence
ORDER BY total DESC
;

Related

order by not working on alias column in mysql query with union all query

SELECT SUM(T1.approve_con) AS compl_rec,
SUM(T1.payout) AS payout,
SUM(T1.reversal) AS reversal,
T1.app_id,
T1.end_user,
T1.created
FROM (
(SELECT app_id,end_user,created,
approve_conversions AS `approve_con`,
'0' AS reversal,
payout AS payout
FROM app_end_users
WHERE publisher_id=1625
AND app_id=57)
UNION ALL
(SELECT opinongold_survey_response.app_id,
opinongold_survey_response.user_id AS end_user,
opinongold_survey_response.movement AS created,
(CASE WHEN opinongold_survey_response.survey_status= 'Completed' THEN 1 ELSE 0 END) AS `approve_con`,
(CASE WHEN opinongold_survey_response.survey_status= 'Rejected' THEN 1 ELSE 0 END) AS reversal,
(CASE WHEN opinongold_survey_response.survey_status= 'Completed' THEN payout ELSE 0 END) AS payout
FROM opinongold_survey_response
WHERE pub_id=1625
AND app_id=57)
) AS T1
GROUP BY T1.app_id,T1.end_user
ORDER BY `approve_con` DESC
LIMIT 0, 10
above is my mysql query order by is not working on approve_con, payout, reversal column
please let me where i am doing wrong in this query.

Aggregate MySQL Queries

Aggregate below queries
1.
SELECT business_id_fk,business_name,
IFNULL(count(orderid_customer),0) AS total,
IFNULL(sum(CASE WHEN order_status IN ('CRD') THEN 1 ELSE 0
END), 0) AS crude,
IFNULL(sum(CASE WHEN order_status IN ('UNA') THEN 1 ELSE 0
END), 0) AS unassigned,
IFNULL(sum(CASE WHEN order_status IN ('DEL' , 'MCP' , 'CMP')
THEN 1 ELSE 0 END), 0) AS delivered,
IFNULL(sum(CASE WHEN order_status IN ('CNL') THEN 1 ELSE 0
END), 0) AS cancelled,
IFNULL(sum(CASE WHEN order_status IN ( 'CAP' , 'CAD' , 'RSP' ,
'RSD') THEN 1 ELSE 0 END), 0) AS postponed,
IFNULL(SUM(total), 0) AS 'Estimated_Revenue',
IFNULL(SUM(CASE WHEN order_status IN ('DEL' , 'MCP', 'CMP')
THEN total ELSE 0 END), 0) AS 'Generated_Revenue'
FROM view_orders where order_datetime between '2017-08-01
00:00:00' and '2017-10-17 23:59:59' and parent_id IS NULL
GROUP BY business_id_fk ORDER BY total DESC;
2.
SELECT A.business_id_fk,A.business_name,ifnull(((A.TotalPrice /
A.TotalQuantity)*100),0) AS 'sla_adherence' FROM (SELECT
business_id_fk,business_name,
sum(sla_del_datetime > delivery_datetime) AS TotalPrice
,sum(order_status in('DEL','MCP','CMP')) AS TotalQuantity
FROM view_orders where parent_id is null and order_datetime between '2017-
08-01 00:00:00' and '2017-10-17 23:59:59'
GROUP BY business_id_fk) AS A;
3.
SELECT A.business_id_fk,A.business_name,ifnull(((A.Totaldelivered /
A.Totalorders)*100),0) AS 'strike_rate' FROM (SELECT
business_id_fk,business_name,
sum(order_status in('DEL','MCP','CMP')) AS Totaldelivered
, count(*) AS Totalorders
FROM view_orders where parent_id is null and order_datetime between '2017-
08-01 00:00:00' and '2017-10-17 23:59:59'
GROUP BY business_id_fk) AS A;
To get the result like
Business_id_fk BusinessName Total Delivered Unassigned Cancelled Postponed EstimatedRevenue GeneratedRevenue SLAadherance Strikerate
2 DEF 10 5 2 1 0 200 100 100 50
1 ABC 20 10 4 2 0 200 100 100 50
Null Null 10 10 0 0 0 100 100 100 100
Here business name having null is Individual customer Orders(non-business orders).
Thank you in advance :-)
Like this:
SELECT
business_id_fk,business_name,
total,
crude,
unassigned,
delivered,
cancelled,
postponed,
Estimated_Revenue,
Generated_Revenue,
TotalPrice,
Totaldelivered,
Totalorders,
ifnull(((TotalPrice / TotalQuantity)*100),0) AS 'sla_adherence',
ifnull(((Totaldelivered / Totalorders)*100),0) AS 'strike_rate'
FROM
(
SELECT
business_id_fk,business_name,
IFNULL(count(orderid_customer),0) AS total,
IFNULL(sum(CASE WHEN order_status IN ('CRD') THEN 1 ELSE 0 END), 0) AS crude,
IFNULL(sum(CASE WHEN order_status IN ('UNA') THEN 1 ELSE 0 END), 0) AS unassigned,
IFNULL(sum(CASE WHEN order_status IN ('DEL' , 'MCP' , 'CMP') THEN 1 ELSE 0 END), 0) AS delivered,
IFNULL(sum(CASE WHEN order_status IN ('CNL') THEN 1 ELSE 0 END), 0) AS cancelled,
IFNULL(sum(CASE WHEN order_status IN ( 'CAP' , 'CAD' , 'RSP' , 'RSD') THEN 1 ELSE 0 END), 0) AS postponed,
IFNULL(SUM(total), 0) AS 'Estimated_Revenue',
IFNULL(SUM(CASE WHEN order_status IN ('DEL' , 'MCP', 'CMP') THEN total ELSE 0 END), 0) AS 'Generated_Revenue',
sum(sla_del_datetime > delivery_datetime) AS TotalPrice,
sum(order_status in('DEL','MCP','CMP')) AS TotalQuantity,
sum(order_status in('DEL','MCP','CMP')) AS Totaldelivered,
count(*) AS Totalorders
FROM view_orders
where order_datetime between '2017-08-01 00:00:00' and '2017-10-17 23:59:59'
and parent_id IS NULL
GROUP BY business_id_fk
) AS A
ORDER BY total DESC;

How can I make this SQL query more elegant?

This is my MySQL query for getting count values...
SELECT 1 AS id,
'2016' AS Year,
MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
COUNT( 1 ) AS Count
FROM reservations
WHERE DATE_FORMAT( created_at, '%Y' ) = '2016'
GROUP BY DATE_FORMAT( created_at, '%m' )
) AS T1
UNION
SELECT 2 AS id,
'2017' AS Year,
MAX( IF( Month = '01', Count, 0 ) ) AS 'VAL01',
MAX( IF( Month = '02', Count, 0 ) ) AS 'VAL02',
MAX( IF( Month = '03', Count, 0 ) ) AS 'VAL03',
MAX( IF( Month = '04', Count, 0 ) ) AS 'VAL04',
MAX( IF( Month = '05', Count, 0 ) ) AS 'VAL05',
MAX( IF( Month = '06', Count, 0 ) ) AS 'VAL06',
MAX( IF( Month = '07', Count, 0 ) ) AS 'VAL07',
MAX( IF( Month = '08', Count, 0 ) ) AS 'VAL08',
MAX( IF( Month = '09', Count, 0 ) ) AS 'VAL09',
MAX( IF( Month = '10', Count, 0 ) ) AS 'VAL10',
MAX( IF( Month = '11', Count, 0 ) ) AS 'VAL11',
MAX( IF( Month = '12', Count, 0 ) ) AS 'VAL12',
SUM( Count ) AS Total
FROM ( SELECT DATE_FORMAT( created_at, '%m' ) AS Month,
COUNT( 1 ) AS Count
FROM reservations
WHERE DATE_FORMAT( created_at, '%Y' ) = '2017'
GROUP BY DATE_FORMAT( created_at, '%m' )
) AS T2
It returns (for example)...
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| id | Year | VAL01 | VAL02 | VAL03 | VAL04 | VAL05 | VAL06 | ... | VAL12 | Total |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| 1 | 2016 | 0 | 0 | 150 | 190 | 200 | 220 | ... | 160 | 1242 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
| 2 | 2017 | 300 | 300 | 600 | 600 | 700 | 0 | ... | 0 | 2500 |
+----+------+-------+-------+-------+-------+-------+-------+-----+-------+-------+
My query has many problems. It can't use the year 2018 and it should use UNION again and again.
How can I make my SQL query more beautiful?
Try this
select
date_format(created_at,'%Y') as Year,
sum(case when date_format(created_at,'%m')='01' then 1 else 0 end) as val01,
sum(case when date_format(created_at,'%m')='02' then 1 else 0 end) as val02,
sum(case when date_format(created_at,'%m')='03' then 1 else 0 end) as val03,
sum(case when date_format(created_at,'%m')='04' then 1 else 0 end) as val04,
sum(case when date_format(created_at,'%m')='05' then 1 else 0 end) as val05,
sum(case when date_format(created_at,'%m')='06' then 1 else 0 end) as val06,
sum(case when date_format(created_at,'%m')='07' then 1 else 0 end) as val07,
sum(case when date_format(created_at,'%m')='08' then 1 else 0 end) as val08,
sum(case when date_format(created_at,'%m')='09' then 1 else 0 end) as val09,
sum(case when date_format(created_at,'%m')='10' then 1 else 0 end) as val10,
sum(case when date_format(created_at,'%m')='11' then 1 else 0 end) as val11,
sum(case when date_format(created_at,'%m')='12' then 1 else 0 end) as val12,
count(*) as total
from reservations
group by date_format(created_at,'%Y')
You can try with below query
SELECT YEAR,SUM(VAL01) VAL02,SUM(VAL02) VAL02,SUM(VAL03) VAL3
FROM
(
SELECT date_format(created_at,'%Y') YEAR,
CASE WHEN date_format(created_at,'%m')=1 THEN 1 ELSE 0 END AS VAL01,
CASE WHEN date_format(created_at,'%m')=2 THEN 1 ELSE 0 END AS VAL02,
CASE WHEN date_format(created_at,'%m')=3 THEN 1 ELSE 0 END AS VAL03
FROM reservations
)t
GROUP BY YEAR
Hope this will helps.
If this had been Oracle, you could have used Function based index on column Created_at and using the same function (EXTRACT in this case) in your query:
CREATE INDEX IDX1 ON RESERVATIONS (EXTRACT(YEAR FROM CREATED_AT))
Since, this is MySQL, try using this as alternative. Make sure after creating the index, it is getting used by verifying the Query plan.
You could try this query
SELECT id,
Year,
SUM(CASE WHEN Month='01' THEN MonthCount ELSE 0 END) AS 'VAL01',
SUM(CASE WHEN Month='02' THEN MonthCount ELSE 0 END) AS 'VAL02',
SUM(CASE WHEN Month='03' THEN MonthCount ELSE 0 END) AS 'VAL03',
SUM(CASE WHEN Month='04' THEN MonthCount ELSE 0 END) AS 'VAL04',
SUM(CASE WHEN Month='05' THEN MonthCount ELSE 0 END) AS 'VAL05',
SUM(CASE WHEN Month='06' THEN MonthCount ELSE 0 END) AS 'VAL06',
SUM(CASE WHEN Month='07' THEN MonthCount ELSE 0 END) AS 'VAL07',
SUM(CASE WHEN Month='08' THEN MonthCount ELSE 0 END) AS 'VAL08',
SUM(CASE WHEN Month='09' THEN MonthCount ELSE 0 END) AS 'VAL09',
SUM(CASE WHEN Month='10' THEN MonthCount ELSE 0 END) AS 'VAL10',
SUM(CASE WHEN Month='11' THEN MonthCount ELSE 0 END) AS 'VAL11',
SUM(CASE WHEN Month='12' THEN MonthCount ELSE 0 END) AS 'VAL12',
SUM(MonthCount) AS Total
FROM (
SELECT
CASE
WHEN Date_format(created_at, '%Y') = '2016' THEN 1
WHEN Date_format(created_at, '%Y') = '2017' THEN 2
WHEN Date_format(created_at, '%Y') = '2018' THEN 3
END AS id,
Date_format(created_at, '%Y') AS Year,
Date_format(created_at, '%m') AS Month,
COUNT(1) AS MonthCount
FROM reservations
WHERE Date_format(created_at, '%Y') IN ('2016', '2017', '2018')
GROUP BY Date_format(created_at, '%Y-%m')) AS ByMonth
GROUP BY id, Year

Methods of speeding up a MySQL Query which has 12 subqueries

The following query returns the correct data but I'd like to see if there's a better way of doing this. The query should return the number of cases for each month within a 12 month period where a record exists within the past 2 months. The idea is to get number of accounts that ordered during the month in question and at least one of the previous 2 months. Also, please note that every value in the table for data_date will always be the 1st of the month.
SELECT
sum(
case
WHEN a.data_date = '2013-03-01'
and exists(
select 1 from sales mth1
where mth1.client_id = a.client_id
and
data_date BETWEEN '2013-01-01'
and
'2013-02-01'
)
then case_qty
ELSE 0 END
) AS M1 ,
sum(
case
WHEN a.data_date = '2013-04-01'
and exists(
select 1 from sales mth2
where mth2.client_id = a.client_id
and mth2.data_date BETWEEN '2013-02-01'
and
'2013-03-01'
)
then case_qty
ELSE 0 END
) AS M2 ,
sum( case WHEN a.data_date = '2013-05-01' and exists( select 1 from sales mth3 where mth3.client_id = a.client_id and mth3.data_date BETWEEN '2013-03-01' and '2013-04-01' ) then case_qty ELSE 0 END) AS M3 ,
sum( case WHEN a.data_date = '2013-06-01' and exists( select 1 from sales mth4 where mth4.client_id = a.client_id and mth4.data_date BETWEEN '2013-04-01' and '2013-05-01' ) then case_qty ELSE 0 END) AS M4 ,
sum( case WHEN a.data_date = '2013-07-01' and exists( select 1 from sales mth5 where mth5.client_id = a.client_id and mth5.data_date BETWEEN '2013-05-01' and '2013-06-01' ) then case_qty ELSE 0 END) AS M5 ,
sum( case WHEN a.data_date = '2013-08-01' and exists( select 1 from sales mth6 where mth6.client_id = a.client_id and mth6.data_date BETWEEN '2013-06-01' and '2013-07-01' ) then case_qty ELSE 0 END) AS M6 ,
sum( case WHEN a.data_date = '2013-09-01' and exists( select 1 from sales mth7 where mth7.client_id = a.client_id and mth7.data_date BETWEEN '2013-07-01' and '2013-08-01' ) then case_qty ELSE 0 END) AS M7 ,
sum( case WHEN a.data_date = '2013-10-01' and exists( select 1 from sales mth8 where mth8.client_id = a.client_id and mth8.data_date BETWEEN '2013-08-01' and '2013-09-01' ) then case_qty ELSE 0 END) AS M8 ,
sum( case WHEN a.data_date = '2013-11-01' and exists( select 1 from sales mth9 where mth9.client_id = a.client_id and mth9.data_date BETWEEN '2013-09-01' and '2013-10-01' ) then case_qty ELSE 0 END) AS M9 ,
sum( case WHEN a.data_date = '2013-12-01' and exists( select 1 from sales mth10 where mth10.client_id = a.client_id and mth10.data_date BETWEEN '2013-10-01' and '2013-12-01' ) then case_qty ELSE 0 END) AS M10 ,
sum( case WHEN a.data_date = '2014-01-01' and exists( select 1 from sales mth11 where mth11.client_id = a.client_id and mth11.data_date BETWEEN '2013-11-01' and '2013-12-01' ) then case_qty ELSE 0 END) AS M11
FROM sales as a
INNER JOIN Products AS P ON P.product_id = a.product_id
WHERE a.client_id IN ('123')
AND a.data_date BETWEEN '2013-03-01' AND '2013-12-01' AND a.case_qty > 0;
Here's a screen shot of the explain
Here's a screen shot of the indexes
change
data_date BETWEEN '2013-01-01' and '2013-02-01'
to
data_date in ('2013-01-01', '2013-01-02',.....,...'2013-02-01' )
but i would turn this whole query into sum cases then use a wrapper to pull out the accounts i need.
From your query it seems like you want the years sales for a product in an entire year. Or something to that affect. So from your data you are almost trying to create a pivot. I had a simlar problem and solved it like this
select
p.product_id,
s.client_id,
sum(case when DATE_FORMAT(a.data_date,'%Y%m') in (201301) then ifnull(case_qty,0) else 0 end) period1,
sum(case when DATE_FORMAT(a.data_date,'%Y%m') in (201301, 201302) then ifnull(case_qty,0) else 0 end) period2,
sum(case when DATE_FORMAT(a.data_date,'%Y%m') in (201301, 201302, 201303) then ifnull(case_qty,0) else 0 end) period3,
sum(case when DATE_FORMAT(a.data_date,'%Y%m') in (201302, 201303, 201304) then ifnull(case_qty,0) else 0 end) period4,
sum(case when DATE_FORMAT(a.data_date,'%Y%m') in (201303, 201304, 201305) then ifnull(case_qty,0) else 0 end) period5,
.
.
.
up to period12
from
sales s
where
a.data_date between '2013-03-01' and '2013-12-31' and
s.client_id = some_value
group by
p.product_id,
s.client_id
Note that the performance of the query has increased drastically since you are only doing a single scan of your sales table (depending on what's in your where clause and indexes). To speed it up you would need indexes on say client_id and data_date for example.
Ideally this query would be run for a report or something where the start and end data is fixed and all the user can change is the year of that date. I wasn't sure if you wanted to group by product_id since in your query you aren't, but you can always remove it to get total per client.
I have adjusted the query based on my understanding in your comments. I am not 100% sure if you can use the keyword 'in' in a case statement. You could alternatively have more case statements.

SQL query - How to exclude WHERE for specific field

See the SQL query below, it work fine. It calculate the number of Yes, NOT, Other and the number of matching mobile number [Sales field] (D.MobileNo = S.mobile)
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
GROUP BY D.Username
ORDER BY TOTAL DESC
I want to exclude WHERE for the Sales field - it should not be part from CheckDate. Meaning it should check any record in the dairy table without CheckDate for the Sales field.
How can that be done?
If you really want those results in only one query, this might do the trick.
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' AND UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL,
SUM(CASE WHEN UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 THEN 1 ELSE 0 END) AS TOTALINCHECKDATE
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
GROUP BY D.Username
ORDER BY TOTAL DESC
Note that "TOTAL" will count all rows (including those who where not within your CheckDate range), TOTALINCHECKDATE return the same value as in your previous query.
Obviously, this can still be optimized.
Assuming username exists also in SALES table
SELECT Username,SUM(Yes) As Yes, SUM(`Not`) As `Not`
, SUM(Other) As Other, SUM(sales) Sales, SUM(total)
FROM (
-- get diary data
SELECT username,mobileNo As mobile,
CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END as Yes,
CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END as `Not`,
CASE WHEN D.type = '' THEN 1 ELSE 0 END as Other,
0 As sales, 1 as total
FROM dairy as D
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
UNION ALL
-- get all sales
SELECT DISTINCT username,mobile, 0 as Yes, 0 as `Not`, 0 As Other, 1 As sales, 0 As total
FROM sales
WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
) AS a
GROUP BY Username
Also try your original query with date addition
SELECT D.Username,
SUM(CASE WHEN D.type = 'Yes' THEN 1 ELSE 0 END) as Yes,
SUM(CASE WHEN D.type = 'Not' THEN 1 ELSE 0 END) as Not,
SUM(CASE WHEN D.type = '' THEN 1 ELSE 0 END) as Other,
SUM(CASE WHEN S.mobile IS NULL THEN 0 ELSE 1 END) as Sales,
COUNT(*) as TOTAL
FROM dairy as D
LEFT JOIN (SELECT DISTINCT mobile FROM sales WHERE UNIX_TIMESTAMP(CheckDate) >= 1309474800 AND UNIX_TIMESTAMP(CheckDate) <= 1311894000 ) as S on D.MobileNo = S.mobile
WHERE source = 'Network'
AND UNIX_TIMESTAMP(CheckDate) >= 1309474800
AND UNIX_TIMESTAMP(CheckDate) <= 1311894000
GROUP BY D.Username
ORDER BY TOTAL DESC