How to merge the result of this 2 queries in mysql server - mysql

I am actually stuck in merging the result of this two queries:
first query:
SELECT c.code, c.name, pc.sku, pc.cat_code, pp.title
FROM `cat_parent` cp, cat c, prod_cat pc, products pp
WHERE c.code = cp.cat_code
AND cp.cat_code = pc.cat_code
AND pp.sku = pc.sku
AND cp.parent_code = 01110
AND hide =0
The result I get is:
Second query:
SELECT `sku` , `update_date` , `description` , count( * ) AS total_sold
FROM `orderline`
WHERE `update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( sku, 7 )
ORDER BY total_sold DESC
The result:
The question I want to ask that how can I get the result by filtering the sku available in both tables.
Just bit confused on that part....any ideas will be appreciated.
This is only part of the data. there is heaps of data. Yes, I want to merge the both tables and want to find the common sku available in both tables.
My expected result will be sku, title, total sold.
Thanks, anyway I managed to get around to get the result.
My final query:
SELECT * FROM (
SELECT sku , update_date , description FROM orderline WHERE
update_date >= '2012-03-06' AND update_date <= '2012-03-07' )g
JOIN (
SELECT c.code, c.name, pc.sku, pc.cat_code FROM cat_parent cp, cat
c, prod_cat pc, products pp WHERE c.code = cp.cat_code AND cp.cat_code
= pc.cat_code AND pp.sku = pc.sku AND cp.parent_code =01110 AND hide =0 )p ON left( g.sku, 7 ) = left( p.sku, 7 )

Something like this -
SELECT
`c`.`code`, `c`.`name`, `pc`.`sku`, `pc`.`cat_code`, `pp.title`,
`ol`.`sku`, `ol`.`update_date`, `ol`.`description`, COUNT(*) AS `total_sold`
FROM `cat_parent` `cp`
INNER JOIN `cat` `c`
ON `c`.`code` = `cp`.`cat_code`
INNER JOIN `prod_cat` `pc`
ON `cp`.`cat_code` = `pc`.`cat_code`
INNER JOIN `products` `pp`
ON `pp`.`sku` = `pc`.`sku`
INNER JOIN `orderline` `ol`
ON LEFT(`pc`.`sku`, 7) = LEFT(`ol`.`sku`, 7)
WHERE `cp`.`parent_code` = 01110
AND `hide` = 0
AND `ol`.`update_date` >= ( DATE_ADD(CURDATE( ) , INTERVAL -14 DAY ) )
AND `ol`.`update_date` <= ( DATE_ADD(CURDATE( ) , INTERVAL -7 DAY ) )
GROUP BY left( `ol`.`sku`, 7 )
ORDER BY `total_sold` DESC

Related

I am missing an alias for a derived table

I know, this question has been asked very often but I know my error, I know how I could fix it, but I canĀ“t find the point where the error is. In my opinion, all the subqueries have different and unique names, I even gave the columns different names then the subqueries. Any help would be appreciated. Where is the point I am missing an alias?
Whenever I am trying to run this query I get the response "Every derived table must have its alias", which is an understandable error message, but I can't figure out where my error is located.
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM
mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
left join (
select
cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate,
avg(repRate.countedOrders) AS avgRepRate
from(
Select
*,
(
select
count(customer_email) AS csc
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS cst,
(
select
count(customer_email) AS cec
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2020-12-31'
) AS cet,
(
select
count(mso_new.customer_email) AS cnc
from
(
select
*
from
mag_sales_flat_order
where
created_at between '2018-01-01'
and current_date()
) AS mso_new
left join (
select
*
from
mag_sales_flat_order
where
created_at between '2017-01-01'
and '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
)) AS cnt
join (
select
customer_email,
count(grand_total) as countedOrders,
sum(grand_total) as summedOrders
from
mag_sales_flat_order
group by
customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE
store_id IN({$store['id']})
AND (
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND (
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY
entity_id;
SELECT
mso.entity_id,
GROUP_CONCAT(msh.comment) AS comment,
msoa.lastname,
base_grand_total,
mso.created_at,
mso.status,
marketplace_order_id AS amazon_order_id,
clvData.recurrenceRate,
clvData.avgRepRate
FROM mag_sales_flat_order AS mso
LEFT JOIN mag_sales_flat_order_status_history AS msh ON mso.entity_id = msh.parent_id
LEFT JOIN mag_sales_flat_order_address AS msoa ON mso.entity_id = msoa.parent_id
LEFT JOIN
(
SELECT cast(((cet.cec - cnt.cnc) / cst.csc) AS decimal(6, 2)) as recurrenceRate, avg(repRate.countedOrders) AS avgRepRate
FROM
(
SELECT *,
(
SELECT count(customer_email) AS csc
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS cst,
(
SELECT count(customer_email) AS cec
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2020-12-31'
) AS cet,
(
SELECT count(mso_new.customer_email) AS cnc
FROM
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2018-01-01' AND getdate()
) AS mso_new
LEFT JOIN
(
SELECT *
FROM mag_sales_flat_order
WHERE created_at BETWEEN '2017-01-01' AND '2017-12-31'
) AS mso_old on mso_new.customer_email = mso_old.customer_email
) AS cnt
) as cl
JOIN
(
SELECT customer_email, count(grand_total) as countedOrders, sum(grand_total) as summedOrders
FROM mag_sales_flat_order
GROUP BY customer_email
) AS repRate on cl.customer_email = repRate.customer_email
) AS clvData on mso.customer_email = clvData.customer_email
WHERE store_id IN({ $ store ['id'] })
AND
(
mso.status = 'complete'
OR mso.status = 'closed'
OR mso.status = 'processing'
OR mso.status = 'exported'
OR mso.status LIKE 'pending%'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') >= '$begin_date'
)
AND
(
DATE_FORMAT(mso.created_at, '%Y-%m-%d') <= '$end_date'
)
GROUP BY entity_id;

Count Total from Multiple Tables

I have list table that basically contains same field on each part.
- p_ticket1_m_site_data | - p_ticket1_ticket | - p_ticket1_last_row
- p_ticket2_m_site_data | - p_ticket2_ticket | - p_ticket2_last_row
- p_ticket3_m_site_data | - p_ticket3_ticket | - p_ticket3_last_row
I can do a count on each table individually:
SELECT COUNT( * ) AS tot_sites, IFNULL( COUNT(
CASE WHEN p_ticket1_m_site_data.m_date_target = DATE( NOW( ) )
THEN 1
ELSE NULL
END ),0) AS todays_target, IFNULL( COUNT(
CASE WHEN (
p_ticket1_m_site_data.m_date_target = DATE( NOW( ) )
AND p_ticket1_ticket.t_status =9 )
THEN 1
ELSE NULL
END ),0
) AS todays_achieve, IFNULL( COUNT(
CASE WHEN p_ticket1_ticket.t_status =9
THEN 1
ELSE NULL
END ),0 ) AS tot_in
FROM p_ticket1_m_site_data
LEFT JOIN p_ticket1_last_row ON p_ticket1_last_row.t_m_id = p_ticket1_m_site_data.m_id
AND p_ticket1_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket1_ticket ON p_ticket1_ticket.t_id = p_ticket1_last_row.t_id
WHERE p_ticket1_m_site_data.m_status =1
What should i do if i want to count all total sites from ticket1, ticket2, ticket3 ?
Please help me guys, thanks . . .
Example use UNION ALL:
I just using UNION ALL in my code above for ticket1 and ticket2, but its not what i want.
My expectation output is count all the ticket tables, so the view is tot_sites (from all ticket), todays_target(from all ticket), todays_achieve(from all ticket), and tot_in(from all ticket)
If you are sure that your tables have the same columns, you should use UNION ALL with CTE
WITH CTE AS (
SELECT *
FROM p_ticket1_m_site_data
UNION ALL
SELECT *
FROM p_ticket2_m_site_data
UNION ALL
...
)
SELECT COUNT(*), ...
FROM CTE
WHERE CTE.m_status = 1
CTE
UNION ALL
You can union the three sets of tables in a sub query and then do your counts in the main query , something like this in principal
SELECT COUNT( * ) AS tot_sites, IFNULL( COUNT(
CASE WHEN m_date_target = DATE( NOW( ) )
THEN 1
ELSE NULL
END ),0) AS todays_target, IFNULL( COUNT(
CASE WHEN (m_date_target = DATE( NOW( ) )
AND t_status =9 )
THEN 1
ELSE NULL
END ),0
) AS todays_achieve, IFNULL( COUNT(
CASE WHEN t_status =9
THEN 1
ELSE NULL
END ),0 ) AS tot_in
from
(
select *
FROM p_ticket1_m_site_data
LEFT JOIN p_ticket1_last_row ON p_ticket1_last_row.t_m_id = p_ticket1_m_site_data.m_id
AND p_ticket1_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket1_ticket ON p_ticket1_ticket.t_id = p_ticket1_last_row.t_id
WHERE p_ticket1_m_site_data.m_status =1
union all
select *
frOM p_ticket2_m_site_data
LEFT JOIN p_ticket2_last_row ON p_ticket2_last_row.t_m_id = p_ticket2_m_site_data.m_id
AND p_ticket2_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket2_ticket ON p_ticket2_ticket.t_id = p_ticket2_last_row.t_id
WHERE p_ticket2_m_site_data.m_status =1
union all
select *
fROM p_ticket3_m_site_data
LEFT JOIN p_ticket3_last_row ON p_ticket3_last_row.t_m_id = p_ticket3_m_site_data.m_id
AND p_ticket3_last_row.t_req_type = '04_int_finish_ack'
LEFT JOIN p_ticket3_ticket ON p_ticket3_ticket.t_id = p_ticket3_last_row.t_id
WHERE p_ticket3_m_site_data.m_status =1
) j;
Which could be tidied up. If this doesn't work for you please add sample data and expected output for your 3 tables as text to the question and I will review.

SQL query adding where related to sub query

Trying to get a where statement on a sub query result. The below works as I want it to, with the exception of AND low_36 != NULL. I need this to stop results where the output of low_36 is NULL.
SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 ) AS low_36
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON v_v.code = offers.code
LEFT JOIN m_f_t ON v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON v.t_t_id = m_t_t.id
WHERE status = 1
AND low_36 != NULL
LIMIT 2 OFFSET 0
I know you can not use results from subqueries in the main where statement, but this is the closest I have come to the correct result. Thank you for any feedback
Quick way would be
SELECT *
FROM
(SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 ) AS low_36
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON v_v.code = offers.code
LEFT JOIN m_f_t ON v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON v.t_t_id = m_t_t.id
WHERE status = 1) a
WHERE low_36 IS NOT NULL
LIMIT 2 OFFSET 0
I suspect you want to exclude null values in the subquery itself, thereby avoiding nullifying your aggregate value. Try this:
SELECT offers.*,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 23 ) AS low_24,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 35 and price is not null) AS low_36,
(SELECT ROUND( MIN( price ) ,2) FROM o_prices WHERE o_id = offers.id AND months = 47 ) AS low_48
FROM offers
LEFT JOIN m_v ON m_v.code = offers.code
LEFT JOIN m_f_t ON m_v.f_t_id = m_f_t.id
LEFT JOIN m_t_t ON m_f_t.t_t_id = m_t_t.id
WHERE status = 1
LIMIT 2 OFFSET 0

Select in select - Every derived table must have its own alias error

I'm trying to get from database information about orders grouped by date.
I have table sales_flat_order, where I have it's id, order creation date, total_paid for order, and order item count. And I have table sales_flat_order_item where are orders items with it prices.
I created script to get order information by day:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items
FROM
sales_flat_order,
sales_flat_order_payment
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP
I get:
DATE SALES ITEMS
2013-03-05 72 3
2013-03-06 100 5
And I have script to count median price:
SELECT
avg(t1.price) as median_val
FROM
(
SELECT
#rownum:=#rownum+1 as `row_number`,
d.price
FROM
sales_flat_order_item d,
(SELECT #rownum:=0) r
WHERE 1
ORDER BY d.price
) as t1,
(
SELECT
count(*) as total_rows
FROM
sales_flat_order_item d
WHERE 1
) as t2
WHERE 1
AND t1.row_number>=total_rows/2
and t1.row_number<=total_rows/2+1;
Now I'm trying to combine this two script to get:
DATE SALES ITEMS median_item_price
2013-03-05 72 3 19
2013-03-06 100 5 10.5
Combined script:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items,
sales_flat_order_item.price as median_item_price
FROM
sales_flat_order,
sales_flat_order_payment,
(
SELECT
avg(t1.price) as median_val
FROM
(
SELECT
#rownum:=#rownum+1 as `row_number`,
d.price
FROM
sales_flat_order_item d,
(SELECT #rownum:=0) r
WHERE 1
ORDER BY d.price
) as t1,
(
SELECT
count(*) as total_rows
FROM
sales_flat_order_item d
WHERE 1
) as t2
WHERE 1
AND t1.row_number>=total_rows/2
and t1.row_number<=total_rows/2+1
) as sales_flat_order_item
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
AND DATE(sales_flat_order_item.created_at) = DATE(sales_flat_order.created_at)
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP
and get error: #1248 - Every derived table must have its own alias
here is database: http://sqlfiddle.com/#!2/7dfec
Can anyone help?
Solution:
SELECT
DATE( sales_flat_order.created_at ) AS date,
SUM( sales_flat_order.total_paid ) AS sales,
SUM( sales_flat_order.total_item_count ) AS items,
MAX( median.median_val ) as median_item_price
FROM
sales_flat_order,
sales_flat_order_payment,
(
SELECT DATE(sq.created_at) as median_date, avg(sq.price) as median_val FROM (
SELECT t1.row_number, t1.price, t1.created_at FROM(
SELECT IF(#prev!=d.created_at, #rownum:=1, #rownum:=#rownum+1) as `row_number`, d.price, #prev:=d.created_at AS created_at
FROM sales_flat_order_item d, (SELECT #rownum:=0, #prev:=NULL) r
ORDER BY d.price
) as t1 INNER JOIN
(
SELECT count(*) as total_rows, created_at
FROM sales_flat_order_item d
GROUP BY created_at
) as t2
ON t1.created_at = t2.created_at
WHERE 1=1
AND t1.row_number>=t2.total_rows/2 and t1.row_number<=t2.total_rows/2+1
)sq
group by DATE(sq.created_at)
) as median
WHERE
sales_flat_order.status = 'complete'
AND sales_flat_order.entity_id = sales_flat_order_payment.parent_id
AND sales_flat_order_payment.method = 'checkmo'
AND median.median_date = DATE( sales_flat_order.created_at )
GROUP BY DATE( sales_flat_order.created_at )
WITH ROLLUP

Why can i sort an inline SELECT value but not use it in a WHERE clause?

I have this small SQL query.
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
AND `grade` >= 5
ORDER BY `grade` DESC
This gives me the error
1054 - Unknown column 'grade' in 'where clause'
But if i remove the 2nd last line, it works fine. I have tried to do AND a.grade and even give the tests table a name and append that name to grade but still no luck.
How can I use this inline query in a WHERE clause?
I have found that this works, but is it the only way?
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
AND (
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) >= 5
ORDER BY `grade` DESC
Sql statements are somewhat evaluated in the following order:
FROM
WHERE
SELECT
GROUP
HAVING
ORDER
So things you define in the SELECT-clause are not available in the WHERE-clause. You would need to put that constraint into a HAVING-clause:
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
HAVING `grade` >= 5
ORDER BY `grade` DESC
SELECT a.`id` , a.`title` , a.`date` ,
(
SELECT MAX( grade )
FROM tests
WHERE userid = 41
AND presid = a.`id`
) AS grade
FROM `presentations` a
WHERE a.`visible` = 1
HAVING `grade` >= 5
ORDER BY
`grade` DESC