GROUP BY in sql to get monthly breakdown of data - mysql

Say I have a data that describes different items sold and when they were sold. I want to breakdown this data and count different items sold on monthly basis. So here is what I have so far:
SELECT
ItemDescription
,OrderReceivedData
,COUNT(*) AS ItemCount
INTO 'C:\Users\whatever.csv'
FROM 'C:\user\inputFileHere.csv'
GROUP BY ItemDescription, OrderReceivedDate
HAVING OrderReceivedDate LIKE '%2011%'
Now the thing is that my dates are in a bad format. So what the query above does is that it shows count for an item on 01JAN2011, 02JAN2011, ... , 10FEB2011, ...and so on. But what I want is the count for JAN2011, FEB2011, MAR2011... and so on. So basically I dont wanna GROUP BY OrderReceivedData but I want to Group by these specific 7 characters in OrderReceivedDate so I can ignore the dates. I hope it makes sense. So how do I do this?

The simple approach, although a bit of a hack, is that you need to parse out the date characters, then group by that. For simplicity, you can reference the column by number. If you think this will change, repeat the parsing logic in your GROUP BY clause. This assumes the field contains two leading characters:
SELECT
ItemDescription
,RIGHT(OrderReceivedData, LEN(OrderReceivedData) - 2) AS MonthOrderReceivedData
,COUNT(*) AS ItemCount
INTO 'C:\Users\whatever.csv'
FROM 'C:\user\inputFileHere.csv'
GROUP BY ItemDescription, 2
HAVING OrderReceivedDate LIKE '%2011%'
I did not test this code, but should get you on the right track.

You first need to make use Log Parser undestands your OrderReceivedDate as a timestamp, and then you format it back as year-month and group by it:
SELECT
ItemDescription,
Month,
COUNT(*) AS TOTAL
USING
TO_STRING(TO_TIMESTAMP(OrderReceivedDate,'ddMMMyyyy'), 'yyyy-MM') as Month
INTO
'C:\Users\whatever.csv'
FROM
'C:\user\inputFileHere.csv'
WHERE
OrderReceivedDate LIKE '%2011%'
GROUP BY
ItemDescription,
Month

SELECT
ItemDescription
,SUBSTR(OrderReceivedDate,2,7) AS OrderReceivedDateUpdated
,COUNT(*) AS ItemCount
INTO 'C:\Users\whatever.csv'
FROM 'C:\user\inputFileHere.csv'
GROUP BY ItemDescription, OrderReceivedDateUpdated
HAVING OrderReceivedDate LIKE '%2011%'

Related

SSRS Sorting by Year group total

I have a tablix that has Customer as the row group and Month and Year as Column Groups. Sales amount is in the data area. I would like to sort the customers in descending order by the Year total sales.
I tried the following (psuedo code)
SELECT
Period (a CONCAT of YEAR(date) and MONTH(Date),
SUM(Amount),
Company
FROM [tables]
Group by Period and Company
ORDER BY Sum(Amount) Desc
I did it this way thinking that if I sorted in the query it would come through in the order I want, but obviously it's showing the customer with the highest single month sales first, not the highest year.
Thinking more about it, if I want the report to be able to span multiple years, then I have to figure out which Year to total on, but I'd be happy to restrict the report to a single Year (identified by a parameter).
When I try to sort the tablix or customer group on Sum(Fields!Amount.value, "xYear") I get the error that aggregates can include groups.
I switched from Tablix to Matrix and now sorting the Customer Group by SUM(Fields!Amount.Value) works.... kind of.
It sorts by the grand total as opposed to a given year, but I can live with that for now. Maybe I'll add a parameter that defaults to the current year and try to figure out how to use that to enforce the sort. I'm thinking I may have to get the total YTD sales by customer in a separate dataset (that doesn't display in the report).
You could do it two ways.. (not tested... it's midnight here...) assuming you have a parameter to select the sort year and the Period is a date - adjust to suit...
You could sort by an expression something like
=SUM(
IIF(
YEAR(Fields!Period.Value) = Parameters!pSortYear.Value,
Fields!Amount.Value,
0),
"myDataSetName")
NOte The dataset name must match your dataset name exactly (case sensitive) and be enclosed in double quotes.
Or.. what I normally do is do it in SQL
SELECT Period, Company, SUM(Amount) AS Amount
INTO #data
FROM myTable
GROUP BY Period, Company
SELECT d.*, s.SortOrder
FROM #data d
JOIN (
SELECT Company, ROW_NUMBER() OVER(ORDER BY Amount DESC) as SortOrder
FROM #data
WHERE Period = #pSortYear
) s on d.Company = s.Company
Then in your report you can simply sort by SortOrder
This is done off he top of my head so there could be some basic errors but hopefully close enough for you to follow.

Trying to multiply columns but can't get the different ones to add when grouping in mySQL

select eventcode, count(eventcode) * price, min(showdate), max(showdate), price
from ticket
group by price;
Please look at the image for better context but I am trying to return the total cost for each eventcode in my query. But when I group by eventcode it doesn't include the different prices that can occur and only returns the first one that it finds. Grouping by price shows the different values that I would like to return together. For example for eventcode 801 I would like to return the total price sum of the 1240 + 2844 + 9850. This is for an assignment and I just can't seem to figure it out. I tried grouping by the count(eventcode) * price but I get an error for invalid use of group function. Sorry for the badly worded question I am just frustrated. Thanks for any help!
If you want the total price for each eventcode, then that should be in the group by:
select eventcode, sum(price), min(showdate), max(showdate)
from ticket
group by eventcode;
Notes:
This returns one row per eventcode. That is how group by works.
You want the total price, so that is sum(price).
You don't want any columns in the select that are not in the group by and not arguments to aggregation functions. Hence, no , price.

Using SQL to count data

Say I have this .csv file which holds data that describes sales of a product. Now say I want a monthly breakdown of number of sales. I mean I wanna see how many orders were received in JAN2005, FEB2005...JAN2008, FEB2008...NOV2012, DEC2012.
Now one very simply way I can think of is count them one by one like this. (BTW I am using logparser to run my queries)
logparser -i:csv -o:csv "SELECT COUNT(*) AS NumberOfSales INTO 'C:\Users\blah.csv' FROM 'C:\User\whatever.csv' WHERE OrderReceiveddate LIKE '%JAN2005%'
My question is if there is a smarter way to do this. I mean, instead of changing the month again and again and running my query, can I write one query which can produce the result in one excel all at one.
Yes.
If you add a group by clause to the statement, then the sql will return a separate count for each unique value of the group by column.
So if you write:
SELECT OrderReceiveddate, COUNT(*) AS NumberOfSales INTO 'C:\Users\blah.csv'
FROM `'C:\User\whatever.csv' GROUP BY OrderReceiveddate`
you will get results like:
JAN2005 12
FEB2005 19
MAR2005 21
Assuming OrderReceiveDate is a date, you would format the date to have a year and month and then aggregate:
SELECT date_format(OrderReceiveddate, '%Y-%m') as YYYYMM, COUNT(*) AS NumberOfSales
INTO 'C:\Users\blah.csv'
FROM 'C:\User\whatever.csv'
WHERE OrderReceiveddate >= '2015-01-01'
GROUP BY date_format(OrderReceiveddate, '%Y-%m')
ORDER BY YYYYMM
You don't want to use like on a date column. like expects string arguments. Use date functions instead.

How to query SQL-database how many times an item has been purchased between two dates?

I'm a beginner when it comes to databases and this question makes my brain melt. I have a database with the standard columns you would imagine: Id, price, description etc. How should I organize the database so that it's possible to query the database how many times an item has been purchased between 2012-01-08 and 2012-03-23?
Concur with the other answers.
SELECT itemcode, count(itemcode) 'times purchased', sum(quantity) 'amount purchased'
FROM `temp_trans`
WHERE `trans_date` >= '2012-01-08' AND `trans_date` <= '2012-03-23'
GROUP BY itemcode
Here's a live example: http://sqlfiddle.com/#!2/13def/1
If you have a date column called dt you can use
SELECT COUNT(Id) FROM your_table
WHERE dt BETWEEN 2012-01-08 AND 2012-03-23
AND Id = your_item_id
select id, count(*)
from mytable
where date between '2012-01-01' and '2012-02-02'
group by id
This gives you the number of times each item was purchased. The field you group by will depend on how you want your result to be split up, using id or a unique name would work depending on what you want to do with the result.
The between clause is inclusive btw
Edit: good point on the comment! Probably should have said "use an appropriate field to group on, like the name or id of the item." in some of our systems description and name are used interchangeably :)

Filter weekly from daily data and pick first occurence of the week

Assume you have a table with a stock time series on a daily basis.
Now you need to filter one data point per week, because you need weekly data for some analysis. You don't to have weekly averages, since this would leave much of the variation out.
This would be my initial approach, but it's not clear which of the data points falling in a given week is selected.
SELECT date, price from stock_series
GROUP BY WEEK(date)
1 How do I make sure it's always the first data point existing for a given week that gets picked?
EDIT:
2 If the above query stayed the way it is - which data point gets chosen every week? What's the MySQL logic in this case? Or is it just unpredictible?
If you want to have a better control over it, you could try using a subquery :
SELECT date,price
FROM stock_series
WHERE date IN
(
SELECT MIN(inner.date)
FROM stock_series inner
GROUP BY WEEK(inner.date)
) GROUP BY date
I've added GROUP BY date in the main query because you probably have more than one entry per day, otherwise it could be ommited.
EDIT:
or try joining with it:
SELECT date,price
FROM stock_series
JOIN
(
SELECT MIN(date) AS innerdate
FROM stock_series
GROUP BY WEEK(date)
) inner ON date=innerdate;
You can order by date ascending, which should give you just the first result of the WEEK() group.
SELECT date,price from stock_series
GROUP BY WEEK(date)
ORDER BY date