Having problems with #variable and Cursor in SQL 2008 - sql-server-2008

--Not sure I am doing this right except what I am doing does not work. I have a list of (vend_num) that I need to run through a query one at a time and compile the results. If any can see/explain where I have gone off the rails it would be greatly appreciated. I have been combing the internet and this site and cannot seem to wrap my brain around it.
--drop table ##ENE_vendUpdate
if object_id('tempdb..##ENE_vendUpdate') is not null
begin
drop table ##ENE_vendUpdate
end
select vend_num
into ##ENE_vendUpdate
from vendor
--select * from ##ENE_vendUpdate
if ##ROWCOUNT > 0
BEGIN
declare #vend_num varchar(7)
declare warrwebcur cursor
for
select vend_num from ##ENE_vendUpdate
open warrwebcur
fetch warrwebcur into #vend_num
while ##FETCH_STATUS = 0
BEGIN
Select a.vend_num,
(SELECT COUNT(*)
FROM po
join matltran mtl on mtl.ref_num = po.po_num
join vendor v on v.vend_num = po.vend_num
where v.vend_num = #vend_num
AND cast(po.CreateDate as datetime) > DATEADD(year,-1,GETDATE())
AND mtl.reason_code = 'PPQ')
AS TOTAL_RMAS,
(SELECT count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
AND poi.stat IN ('C','F'))
AS PO_Lines_Complete,
(SELECT count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE()))
AS PO_Lines_Total,
(SELECT sum(qty)
FROM po
join matltran mtl on mtl.ref_num = po.po_num
join vendor v on v.vend_num = po.vend_num
where v.vend_num = #vend_num
AND cast(po.CreateDate as datetime) > DATEADD(year,-1,GETDATE())
AND mtl.reason_code = 'PPQ')
AS RMA_Pieces ,
(SELECT sum(poi.qty_received)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
AND poi.stat in ('C','F') )
AS PCs_Received,
(SELECT sum(poi.qty_ordered)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE()) AND poi.stat in ('C','F'))
AS PCs_Due,
(SELECT count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num
AND poi.rcvd_date <= poi.due_date
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE()) )
AS PO_Lines_OnTime,
(SELECT count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num
AND cast(po.CreateDate as datetime) > DATEADD(year,-1,GETDATE())
AND poi.rcvd_date is null)
AS PO_Lines_due,
(select count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
AND poi.stat in ('C','F'))
AS ONTIME_PERCT,
(select count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
AND poi.stat in ('C','F'))
AS TOTAL_ROW_COUNT,
(SELECT count(*)
FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num
AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
AND poi.stat IN ('C','F')
AND poi.qty_ordered <> poi.qty_received)
AS PO_Lines_Accurate
FROM (SELECT DISTINCT v.vend_num FROM vendor v
join po on v.vend_num = po.vend_num
join vendaddr on vendaddr.vend_num = v.vend_num
join PoItem poi on poi.po_num = po.po_num
where v.vend_num = #vend_num AND cast(poi.rcvd_date as datetime) > DATEADD(year,-1,GETDATE())
) A

Your TSQL doesn't look complete. It should look something like this:
DECLARE warrwebcur CURSOR FOR
select vend_num from ##ENE_vendUpdate
OPEN warrwebcur
FETCH NEXT FROM warrwebcur INTO #vend_num
WHILE ##FETCH_STATUS = 0
BEGIN
-- your query
FETCH NEXT FROM warrwebcur INTO #vend_num
END
CLOSE warrwebcur
DEALLOCATE warrwebcur

Related

MYSQL - Stored Procedure Query Simplify

I am new to MYSQL.
I need to customize this query. Now I am using only the IF condition and the query length is too big.
In this stored procedure only we change 'f.status' value based on _status value
EX:
__status = 'ALL'
ON f.financeId = t.financeId where f.status=0;
__status = 'PAID'
ON f.financeId = t.financeId where f.status=1;
__status = 'UNPAID'
ON f.financeId = t.financeId where f.status=2;
Query:
DELIMITER ;;
CREATE DEFINER=`root`#`localhost` PROCEDURE `all_data_search`(
_status VARCHAR(50)
)
BEGIN
IF (_status='All') THEN
SELECT
f.financeId,
f.customerId,
c.customerName,
c.initial,
c.phone1,
c.aadhaar,
f.financeStartDate,
f.vehicleNumber,
f.loanAmount,
f.totalInstallment,
f.installmentAmount,
COALESCE(t.payedInstallment, 0) as payedInstallment,
f.status,
f.created_by,
f.created_date,
f.updated_by,
f.updated_date
FROM finance f
INNER JOIN customer c
ON c.customerId = f.customerId
LEFT JOIN
(
SELECT financeId, COUNT(status) AS payedInstallment
FROM financeinstallment
WHERE status = 1
GROUP BY financeId
) t
ON f.financeId = t.financeId;
END IF;
IF (_status='0') THEN
SELECT
f.financeId,
f.customerId,
c.customerName,
c.initial,
c.phone1,
c.aadhaar,
f.financeStartDate,
f.vehicleNumber,
f.loanAmount,
f.totalInstallment,
f.installmentAmount,
COALESCE(t.payedInstallment, 0) as payedInstallment,
f.status,
f.created_by,
f.created_date,
f.updated_by,
f.updated_date
FROM finance f
INNER JOIN customer c
ON c.customerId = f.customerId
LEFT JOIN
(
SELECT financeId, COUNT(status) AS payedInstallment
FROM financeinstallment
WHERE status = 1
GROUP BY financeId
) t
ON f.financeId = t.financeId where f.status=0;
END IF;
IF (_status = 'PAID') THEN
SELECT
f.financeId,
f.customerId,
c.customerName,
c.initial,
c.phone1,
c.aadhaar,
f.financeStartDate,
f.vehicleNumber,
f.loanAmount,
f.totalInstallment,
f.installmentAmount,
COALESCE(t.payedInstallment, 0) as payedInstallment,
f.status,
f.created_by,
f.created_date,
f.updated_by,
f.updated_date
FROM finance f
INNER JOIN customer c
ON c.customerId = f.customerId
LEFT JOIN
(
SELECT financeId, COUNT(status) AS payedInstallment
FROM financeinstallment
WHERE status = 1
GROUP BY financeId
) t
ON f.financeId = t.financeId where f.status=1;
END IF;
IF (_status = 'UNPAID') THEN
SELECT
f.financeId,
f.customerId,
c.customerName,
c.initial,
c.phone1,
c.aadhaar,
f.financeStartDate,
f.vehicleNumber,
f.loanAmount,
f.totalInstallment,
f.installmentAmount,
COALESCE(t.payedInstallment, 0) as payedInstallment,
f.status,
f.created_by,
f.created_date,
f.updated_by,
f.updated_date
FROM finance f
INNER JOIN customer c
ON c.customerId = f.customerId
LEFT JOIN
(
SELECT financeId, COUNT(status) AS payedInstallment
FROM financeinstallment
WHERE status = 1
GROUP BY financeId
) t
ON f.financeId = t.financeId where f.status=2;
END IF;
END ;;
DELIMITER ;
declare status_flag smallint;
....
IF (_status = 'ALL') THEN status_flag=0;
ELSEIF (_status = 'PAID') THEN status_flag=1;
ELSEIF (_status = 'UNPAID') THEN status_flag=2;
ENDIF;
....
WHERE status = status_flag
You can use boolean operation as follows:
ON f.financeId = t.financeId
where (__status = 'ALL' and f.status=0)
or (__status = 'PAID' and f.status=1)
or (__status = 'UNPAID' and f.status=2);

Is there way to group the column in mysql in 3 categories

I have question regarding on my script, If i use the group by the output that I want to get is wrong, however if I remove the group by statement the output is correct but the grouping of 3 categories multiples times shown
I want the output look likes this:.
Ex.
My Output:
My Script:
SELECT store,
CASE priority_level
WHEN '3' THEN 'High Priority'
WHEN '2' THEN 'Medium Priority'
WHEN '1' THEN 'Low Priority'
END as priority_level,
CAST(CASE priority_level
WHEN '3' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 8 HOUR),(SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history ) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '3'),'0')
WHEN '2' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 3 DAY),(SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history ) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '2'),'0')
WHEN '1' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 5 DAY),(SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history ) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '1'),'0')
END AS CHAR(10000) CHARACTER SET utf8) as total_hit,
CASE priority_level
WHEN '3' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 8 HOUR),CONCAT(ROUND((100 / (SELECT COUNT(*) FROM repair_history WHERE priority_level ='3' AND store ='1130') * (SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '3'))),'%'),'0')
WHEN '2' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 3 DAY),CONCAT(ROUND((100 / (SELECT COUNT(*) FROM repair_history WHERE priority_level ='2' ) * (SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '2'))),'%'),'0')
WHEN '1' THEN IF(date_received >= DATE_SUB(date_finished,INTERVAL 5 DAY),CONCAT(ROUND((100 / (SELECT COUNT(*) FROM repair_history WHERE priority_level ='1' ) * (SELECT COUNT(*) FROM is_mr_done as imd
LEFT JOIN (SELECT mr_no,priority_level FROM repair_history) rh
ON imd.mr_no = rh.mr_no
WHERE is_done = '1' AND rh.priority_level = '1'))),'%'),'0')
END as total_hit_average
FROM repair_history as rh
LEFT JOIN (SELECT mr_no,is_done,date_finished FROM is_mr_done) imd
ON rh.mr_no = imd.mr_no
WHERE priority_level != ''
Table Repair History:
Table mr_is_done:

Add Columns for multiple attributes in MySQL

I'm really not sure how to explain this, since I just started trying to learn how to use MySQL queries in a more advanced way today. Here is what I have:
SELECT pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319;
So I have that query, and literally, all I want to do is add another column for the "And an.attributeid = 113319"
I just want to add another column but instead of 113319, I want it to pull the values of let's say 1762 into a column next to it.
So column 1 would have all the values that "And an.attributeid = 113319" pulls, and column two would have all the values that "And an.attributeid = 1762" pulls.
I got this code to work kind of:
SELECT pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319;
SELECT pa.displayvalue as Type
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1762;
But this is returned in navicat as two seperate results. I want both of these to be in one result but as two columns, instead of two results with one column each.
As you can see, all of the lines are the same in each of those Selects except that last line.
I also feel like there is a better way than to have to use that whole code twice just to get another column for an.attributeid. Regardless, I'll take what I can get.
If you have ANY suggestions, I would appreciate it very very much.
If you really want to do that, for formatting or reporting purpose. This is a hack you would use.
And the use of LEFT JOIN would return all rows from the left table, with the matching rows in the right table. The result is NULL in the right side when there is no match.
SELECT p.productid, t2.Type, t1.Brand, t3.Resolution
FROM product p
JOIN
(
SELECT p.productid, pa.displayvalue as Brand
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 113319
) t1 ON t1.productid = p.productid
LEFT OUTER JOIN
(
SELECT p.productid, pa.displayvalue as Type
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1100
) t2 ON t2.productid = p.productid
LEFT OUTER JOIN
(
SELECT p.productid, pa.displayvalue as Resolution
FROM product p
JOIN categoryheader ch ON ch.templatetype = 0 AND p.categoryid=ch.categoryid AND ch.isactive=1
JOIN categorydisplayattributes cda ON ch.headerid = cda.headerid AND ch.categoryid = cda.categoryid AND cda.templatetype = ch.templatetype AND cda.isactive=1
JOIN productattribute pa ON p.productid = pa.productid AND cda.attributeid = pa.attributeid AND pa.localeid = 1 AND pa.isactive =1
JOIN attributenames an ON pa.attributeid = an.attributeid AND an.localeid = 1
WHERE p.isactive = 1 AND p.categoryid = 4871
AND an.attributeid = 1762
) t3 ON t3.productid = p.productid
You can do something like this
... AND an.attributeid IN (113319, 1762 )
This would return you two rows with one column.
If you want to transpose rows into columns, then that gets a bit more complicated.
This is sometimes called a key-value store. You need to play some games with multiple joins to do what you want.
This sort of thing will do the trick
SELECT whatever,
attr1.displayvalue attr1,
attr2.displayvalue attr2
FROM product p
LEFT JOIN productattribute attr1 ON p.productid = attr1.productid
AND attr1.attributeid = 113319
AND attr1.localeid = 1
AND attr1.isactive = 1
LEFT JOIN productattribute attr2 ON p.productid = attr2.productid
AND attr2.attributeid = 1762
AND attr2.localeid = 1
AND attr2.isactive = 1
You end up joining two copies of the attribute table, and selecting the appropriate attribute id from each in the join condition. You use left join rather than ordinary join so you still get the row even if the attribute is missing.
A very common example in the wild of this data organization is the wp_postmeta table in WordPress.

Syntax Error during inner join of two select statements

The sql query below is having some error during inner join part and this is the error message:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'AS a INNER JOIN (SELECT SERIAL_NO FROM STOCK.WAREHOUSE_MVT_LINE
mvtLn INNER ' at line 3
SELECT
wm.CID,
wm.DOC_ID,
wm.DOC_TYPE,
wml.SERIAL_NO,
wml.WH_MVT_NO,
wm.PROD_ID,
wm.LOT_CODE,
wm.WH_CODE,
wm.BIN_CODE,
wml.MVT_DATE,
wm.BATCH_NO,
wm.MVT_TYPE,
wm.PROD_NAME,
wm.COMMENT,
wm.REMARK,
wm.NOTE,
wm.INSTRUCTION
FROM
STOCK.WAREHOUSE_MVT_LINE wml
INNER JOIN
STOCK.WAREHOUSE_MVT wm
ON wml.CID=wm.CID
AND wml.WH_MVT_NO=wm.WH_MVT_NO
WHERE
wml.CID = 70200009
AND (
wm.MVT_TYPE != 'TFOUT'
AND wm.MVT_TYPE != '3TFOUT'
)
AND wml.SERIAL_NO IN (
(
SELECT
SERIAL_NO
FROM
STOCK.WAREHOUSE_MVT_LINE mvtLn
INNER JOIN
STOCK.WAREHOUSE_MVT mvt
ON mvtLn.CID = mvt.CID
AND mvtLn.PFC_CODE = mvt.PFC_CODE
AND mvtLn.WH_MVT_NO = mvt.WH_MVT_NO
where
mvtLn.CID = 70200009
AND mvtLn.PFC_CODE ='SG'
AND mvtLn.MVT_DATE >= '2016-04-01 00:00:00.0'
AND mvtLn.MVT_DATE <='2016-06-30 00:00:00.0'
AND mvt.WH_CODE = 'IDJKT'
AND mvt.BIN_CODE = 'IMP'
)AS a
INNER JOIN
(
SELECT
SERIAL_NO
FROM
STOCK.WAREHOUSE_MVT_LINE mvtLn
INNER JOIN
STOCK.WAREHOUSE_MVT mvt
ON mvtLn.CID = mvt.CID
AND mvtLn.PFC_CODE = mvt.PFC_CODE
AND mvtLn.WH_MVT_NO = mvt.WH_MVT_NO
where
mvtLn.CID = 70200009
AND mvtLn.PFC_CODE ='SG'
AND mvtLn.MVT_DATE >= '2016-01-01 00:00:00.0'
AND mvtLn.MVT_DATE <='2016-03-31 00:00:00.0'
AND mvt.WH_CODE = 'CL'
AND mvt.BIN_CODE = 'PSADEPOT'
)AS b
ON a.SERIAL_NO = b.SERIAL_NO
)
AND wm.MVT_DATE BETWEEN '2016-01-01 00:00:00.0' AND '2016-06-30 00:00:00.0'
ORDER BY
wml.SERIAL_NO,
wml.MVT_DATE
Do you want this?
SELECT wm.CID, wm.DOC_ID, wm.DOC_TYPE, wml.SERIAL_NO, wml.WH_MVT_NO
, wm.PROD_ID, wm.LOT_CODE, wm.WH_CODE, wm.BIN_CODE, wml.MVT_DATE
, wm.BATCH_NO, wm.MVT_TYPE, wm.PROD_NAME, wm.COMMENT, wm.REMARK
, wm.NOTE, wm.INSTRUCTION
FROM STOCK.WAREHOUSE_MVT_LINE wml INNER JOIN STOCK.WAREHOUSE_MVT wm ON wml.CID = wm.CID
AND wml.WH_MVT_NO = wm.WH_MVT_NO
WHERE wml.CID = 70200009
AND wm.MVT_TYPE != 'TFOUT'
AND wm.MVT_TYPE != '3TFOUT'
AND wml.SERIAL_NO IN (
SELECT a.SERIAL_NO FROM -- You missed this. I thought....
(
SELECT SERIAL_NO
FROM STOCK.WAREHOUSE_MVT_LINE mvtLn
INNER JOIN STOCK.WAREHOUSE_MVT mvt
ON mvtLn.CID = mvt.CID
AND mvtLn.PFC_CODE = mvt.PFC_CODE
AND mvtLn.WH_MVT_NO = mvt.WH_MVT_NO
WHERE mvtLn.CID = 70200009
AND mvtLn.PFC_CODE = 'SG'
AND mvtLn.MVT_DATE >= '2016-04-01 00:00:00.0'
AND mvtLn.MVT_DATE <= '2016-06-30 00:00:00.0'
AND mvt.WH_CODE = 'IDJKT'
AND mvt.BIN_CODE = 'IMP'
) a
INNER JOIN (
SELECT SERIAL_NO
FROM STOCK.WAREHOUSE_MVT_LINE mvtLn
INNER JOIN STOCK.WAREHOUSE_MVT mvt
ON mvtLn.CID = mvt.CID
AND mvtLn.PFC_CODE = mvt.PFC_CODE
AND mvtLn.WH_MVT_NO = mvt.WH_MVT_NO
WHERE mvtLn.CID = 70200009
AND mvtLn.PFC_CODE = 'SG'
AND mvtLn.MVT_DATE >= '2016-01-01 00:00:00.0'
AND mvtLn.MVT_DATE <= '2016-03-31 00:00:00.0'
AND mvt.WH_CODE = 'CL'
AND mvt.BIN_CODE = 'PSADEPOT'
) b ON a.SERIAL_NO = b.SERIAL_NO )
AND wm.MVT_DATE BETWEEN '2016-01-01 00:00:00.0' AND '2016-06-30 00:00:00.0'
ORDER BY wml.SERIAL_NO, wml.MVT_DATE

Optimizing MySQL query for fetching data using time range

I'm building a line chart for a product sales report by using the Google Chart API and are separating the data on a per day basis with basically running the same query in a loop for each day using UNION ALL as glue.
E.g. A report for a whole year will repeat the query, using UNION ALL 365 times.
I'm guessing this is not a -best practice- example so if anyone would be so kind and point me in the right direction of how to optimize this query, I would greatly appreciate it.
SELECT SUM(op.qty) AS qty
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247695200) AND (o.created < 1247781600)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
UNION ALL
SELECT SUM(op.qty) AS qty
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247781600) AND (o.created < 1247868000)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
UNION ALL
SELECT SUM(.......
Thanks for all the quick replies! With the query example from jspcal, my query ended up like this:
SELECT SUM(op.qty) AS qty, DATE_FORMAT(FROM_UNIXTIME(o.created),'%d-%m-%Y') AS day
FROM uc_order_products op
LEFT JOIN uc_orders o ON o.order_id = op.order_id
LEFT JOIN node n ON n.nid = op.nid
LEFT JOIN node_type nt ON nt.type = n.type
WHERE (o.created > 1247695200) AND (o.created < 1263596400)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
GROUP BY day
And with PHP, I combine a complete date range array (matching array keys with strtotime($data->day) from the query result) to get days with no sale.
you can group by day:
select sum(op.qty) as qty, date_format(o.created, '%Y-%m-%d') as day
from ... where ... o.created >= subdate(now(), interval 1 year) and
o.created <= now() group by day order by day
will report the sum for each day of the year in the data set
You sould be able to convert
WHERE (o.created > 1247695200) AND (o.created < 1247781600)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
WHERE (o.created > 1247781600) AND (o.created < 1247868000)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')
....
To something like
WHERE (
(o.created > 1247695200) AND (o.created < 1247781600)
OR (o.created > 1247781600) AND (o.created < 1247868000)
...
)
AND (o.order_status = 'completed')
AND (nt.type = 'book' OR nt.type = 'digital_movie')