mysql Select from Select - mysql

I have this query:
SELECT DATE( a.created_at ) AS order_date, count( * ) as cnt_order
FROM `sales_order_item` AS a
WHERE MONTH( a.created_at ) = MONTH( now())-1
GROUP BY order_date
which will return result something like this (snapshot only otherwise will return per 31 days):
order_date cnt_order
2012-08-29 580
2012-08-30 839
2012-08-31 1075
and my full query is selecting based on above selection:
SELECT order_date
, MAX(cnt_order) AS highest_order
FROM (
SELECT DATE (a.created_at) AS order_date
, count(*) AS cnt_order
FROM `sales_order_item` AS a
WHERE MONTH(a.created_at) = MONTH(now()) - 1
GROUP BY order_date
) AS tmax
But it result :
order_date highest_order
2012-08-01 1075
Which has the date wrong and always pick the first row of date where it suppose 2012-08-31. Maybe this is a simple error that I dont know. So how to get the date right point to 2012-08-31? Any help would be great.

You could try ordering the sub query result set; something like:
SELECT
DATE (a.created_at) AS order_date,
COUNT(*) AS cnt_order
FROM
`sales_order_item` AS a
WHERE
MONTH(a.created_at) = MONTH(now()) - 1
GROUP BY
order_date
ORDER BY
cnt_order DESC

You can add ORDER BY order_date DESC in subquery.

Related

how to get the weeks b/w two dates as week1,week2,week3 in mysql

SELECT COUNT(order_id) AS xAxis,
WEEK(created_at) AS yAxis
FROM orders WHERE created_at >= startDate
AND created_at <= endDate GROUP BY WEEK(created_at);
Try just using MIN and MAX:
SELECT
COUNT(order_id) AS xAxis,
WEEK(created_at) AS yAxis,
MIN(created_at) AS week_start,
MAX(created_at) AS week_end
FROM orders
WHERE
created_at BETWEEN startDate AND endDate
GROUP BY
WEEK(created_at);
The reasoning here is simple: the start of each week group of records should be the smallest date and vice-versa for the max.
Should your data not cover every day in the range, then you can join to a calendar table to bring in the missing dates. The updated query would now look something like:
SELECT
COUNT(o.order_id) AS xAxis,
WEEK(t.dt) AS yAxis,
MIN(t.dt) AS week_start,
MAX(t.dt) AS week_end
FROM
(
SELECT '2020-01-01' AS dt UNION ALL
SELECT '2020-01-02' UNION ALL
...
SELECT '2020-12-31'
) t
LEFT JOIN orders o
ON t.dt = o.created_at
WHERE
o.created_at BETWEEN startDate AND endDate
GROUP BY
WEEK(t.dt);
See here for more information on generating date tables in MySQL.

Getting all orders, where the last order ist older than a year in mySql

I have a mySQL table, which holds:
CustomerId and OrderDate
There can me multiple rows for one CustomerId
Now, I try to get the CustomerId's where only the last OrderDate is older than a year.
I try the following:
SELECT *
FROM order
WHERE OrderDate <=DATE_SUB(now(), Interval 1 Year)
GROUP BY CustomerId
ORDER BY OrderDate DESCC;
The problem here is, that I get all the rows, which are older then 1 year.
But as I said above, I try to get only the latest order, which is older than 1 year.
THX for any advise
Order the rows and limit to the last. Also, you had DESCC instead of DESC.
SELECT *
FROM order
WHERE OrderDate <=DATE_SUB(now(), Interval 1 Year)
GROUP BY CustomerId
ORDER BY OrderDate DESC
LIMIT 1;
You might also try this query:
SELECT
`CustomerId`,
`CustomerName`, // Add other fields you want returned.
MAX(`OrderDate`)
FROM `order`
WHERE `OrderDate` <= DATE_SUB(now(), Interval 1 Year)
GROUP BY `CustomerId`
ORDER BY MAX(`OrderDate`) DESC;
Also, this will return all of the related columns in the last order for each customer:
SELECT *
FROM `order` a
JOIN (
SELECT
`CustomerId`,
MAX(`OrderDate`) as `maxdate`
FROM `order`
WHERE `OrderDate` <= DATE_SUB(now(), Interval 1 Year)
GROUP BY `CustomerId`) b
ON a.`CustomerId` = b.`CustomerId` AND
a.`OrderDate` = b.`maxdate`
ORDER BY `maxdate` DESC;
Try this subquery:
select customer_id
from customer table
where order_id in(Select order_id from (select order_id from order_table (year(now())-year(order_date)) = 1 order by order_date desc limit 1))
if it doesn't work please post your table structure.
THX for all your tips.
At the end, I found my working solution:
SELECT
*
FROM order a1
INNER JOIN (SELECT
order.Id
FROM (SELECT
*
FROM (SELECT
*
FROM order
WHERE OrderDate <= DATE_SUB(NOW(), INTERVAL 1 year)
ORDER BY OrderDate DESC) AS Sub
GROUP BY Sub.CustomerId) AS a2) AS a3
ON a1.id = a3.id;

Need help in executing SQL query

Here are two queries with results, I need to run one query to get same result.
1-Total slots
2-created Date
3-start date
4-end date
5-Unused Slots
First Query:-
SELECT COUNT( id ) as total_slots ,
created_date, MIN( DATE ) as start_date ,
MAX( DATE ) as end_date
FROM slots
GROUP BY created_date;
Query 1(Result)
Here is image with query result
Can I get unused slots in same query as I am getting from below query?
But here
SELECT COUNT( id ) AS unused
FROM slots
WHERE user_id =0
AND created_date = '2016-10-01 20:20:20'
Result Query with created date 2016-10-01 20:20:20
unused
79
SELECT COUNT( id ) AS unused
FROM slots
WHERE user_id =0
AND created_date = '2016-10-01 20:24:45'
Result Query with created date 2016-10-01 20:24:45
unused
51
Try
SELECT
COUNT( id ) as total_slots,
created_date,
MIN( DATE ) as start_date,
MAX( DATE ) as end_date,
COUNT(CASE WHEN user_id = 0 THEN 1 END) as unused_slots
FROM slots
GROUP BY created_date;

MySQL Query NOT IN another Query

SELECT DISTINCT d.customer_id, d.date_added FROM `order` d
WHERE d.customer_id NOT IN (
SELECT DISTINCT i.customer_id
FROM `order` i
WHERE i.date_added > '2015-02-15 14:00:00'
)
ORDER BY d.date_added DESC;
The above query should return customer_id of customers who have not ordered after 15 Feb 2015 (I think). But very first record is
17168, 2015-08-16 17:36:00
What am I doing wrong?
This below query
SELECT DISTINCT i.customer_id,i.date_added FROM `order` i
WHERE i.date_added > '2015-02-15 14:00:00'
ORDER BY i.date_added ASC;
returns expected result i.e. list of customer ids for orders placed after 15 Feb
P.S. customer_id can not be NULL
Can customer_id or data_added be NULL? Try
SELECT DISTINCT d.customer_id,d.date_added
FROM order d
WHERE d.customer_id NOT IN
(SELECT DISTINCT i.customer_id FROM order i
WHERE i.date_added > '2015-02-15 14:00:00'
and customer_id IS NOT NULL
and i.date_added IS NOT NULL)
ORDER BY d.date_added DESC;
Edit
The way you wrote your query will get you customer_ids with an order before '2015-02-15 14:00:00'. But if the customer ordered something after this date they might be in the resultset.
Edit2
Why not write
SELECT DISTINCT customer_id, date_added
FROM order
WHERE date_added <= '2015-02-15 14:00:00'
ORDER BY date_added DESC;
I would use a correlated not exists query to exclude all customers that have any order after the specified date:
SELECT o1.customer_id, o1.date_added
FROM `order` o1
WHERE NOT EXISTS (
SELECT 1
FROM `order` o2
WHERE date_added > '2015-02-15 14:00:00'
AND o1.customer_id = o2.customer_id
)
ORDER BY o1.date_added DESC;
If you want customers who have not ordered since a certain date, I would just use group by and having:
SELECT o.customer_id, MAX(o.date_added) as most_recent
FROM `order` o
GROUP BY o.customer_id
HAVING MAX(o.date_added) <= '2015-02-15 14:00:00';

Get the most popular product per day, MySQL for Magento

I need to get a table that contains the most popular product sold per day. All data is stored in Magento, and I use MySQL to write the query. The only table I need is Sales_flat_order_item table.
The final table should have 3 columns: Date, Product SKU, and number of units sold of the most popular product that day - MaxQty.
I came up with the query that works for me, but I would like to know how it can be improved since I use the same subquery twice in my code:
1 Select Date, Product Id, Sku, and Quantity from sales_flat_order_item - Subquery1
2 Select Date and Maximum Quantity from Subquery1 - Subquery2
3 Join them together knowing that dates should be the same, and Quantity from Subquery1 should be equal to Maximum Quantity from Subquery2
SELECT DATE( sq2.created_at ) AS CreatedAt, sq0.sku AS SKU, sq2.MaxQty
FROM (
SELECT created_at, product_id, sku, SUM( qty_ordered ) AS qty
FROM `sales_flat_order_item`
GROUP BY DATE( created_at ) , product_id
) AS sq0
JOIN (
SELECT sq.created_at, MAX( sq.qty ) AS MaxQty
FROM (
SELECT created_at, product_id, SUM( qty_ordered ) AS qty
FROM `sales_flat_order_item`
GROUP BY DATE( created_at ) , product_id
) AS sq
GROUP BY DATE( sq.created_at )
) AS sq2 ON DATE( sq2.created_at ) = DATE( sq0.created_at )
AND sq2.MaxQty = sq0.qty
GROUP BY DATE( CreatedAt )
I believe this should do what you want.
I added a WHERE clause to run it only for this month, in case you have a huge database so it should not take much time.
SELECT day, sku, MAX(qty_total) AS qty FROM (
SELECT DATE(created_at) AS day, sku, SUM(qty_ordered) AS qty_total
FROM `sales_flat_order_item`
WHERE created_at > '2015-07%'
GROUP BY sku, day
ORDER BY qty_total DESC
) AS item_count
GROUP BY day