SQL based on my Example for Month - sql

I am new to SQL and Learning on my own. I was wondering if someone can help guiding me to a write SQL.
I have the below data:
I am using the following query:
SELECT
TIMESTAMP
DATEPART(Year, TIMESTAMP) Year,
DATEPART(Month, TIMESTAMP) Month,
COUNT(*) [Total Rows]
FROM
stage.ACTIVITY_ACCUMULATOR_archive
WHERE
TIMESTAMP BETWEEN '01-Jan-2014' AND '30-June-2014'
GROUP BY
DATEPART(Year, TIMESTAMP), DATEPART(Month, TIMESTAMP)
ORDER BY
Year, Month
What I am trying to achieve is to display the Timestamp with year and month between the certain date and group them by month and year.
I get an error:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'Year'

This should work.There was a extra timestamp column in select list.
SELECT
DATEPART(Year, TIMESTAMP) Year,
DATEPART(Month, TIMESTAMP) Month,
COUNT(*) [Total Rows]
FROM
stage.ACTIVITY_ACCUMULATOR_archive
WHERE
TIMESTAMP BETWEEN '01-Jan-2014' AND '30-June-2014'
GROUP BY
DATEPART(Year, TIMESTAMP), DATEPART(Month, TIMESTAMP)
ORDER BY
Year, Month

Related

PostgreSQL: Simplifying a SQL query into a shorter query

I have a table called 'daily_prices' where I have 'sale_date', 'last_sale_price', 'symbol' as columns.
I need to calculate how many times 'last_sale_price' has gone up compared to previous day's 'last_sale_price' in 10 weeks.
Currently I have my query like this for 2 weeks:
select count(*) as "timesUp", sum(last_sale_price-prev_price) as "dollarsUp", 'wk1' as "week"
from
(
select last_sale_price, LAG(last_sale_price, 1) OVER (ORDER BY sale_date) as prev_price
from daily_prices
where sale_date <= CAST('2020-09-18' AS DATE) AND sale_date >= CAST('2020-09-14' AS DATE)
and symbol='AAPL'
) nest
where last_sale_price > prev_price
UNION
select count(*) as "timesUp", sum(last_sale_price-prev_price) as "dollarsUp", 'wk2' as "week"
from
(
select last_sale_price, LAG(last_sale_price, 1) OVER (ORDER BY sale_date) as prev_price
from daily_prices
where sale_date <= CAST('2020-09-11' AS DATE) AND sale_date >= CAST('2020-09-07' AS DATE)
and symbol='AAPL'
) nest
where last_sale_price > prev_price
I'm using 'UNION' to combine the weekly data. But as the number of weeks increase the query is going to be huge.
Is there a simpler way to write this query?
Any help is much appreciated. Thanks in advance.
you can extract week from sale_date. then apply group by on the upper query
select EXTRACT(year from sale_date) YEAR, EXTRACT('week' FROM sale_date) week, count(*) as "timesUp", sum(last_sale_price-prev_price) as "dollarsUp"
from (
select
sale_date,
last_sale_price,
LAG(last_sale_price, 1) OVER (ORDER BY sale_date) as prev_price
from daily_prices
where symbol='AAPL'
)
where last_sale_price > prev_price
group by EXTRACT(year from sale_date), EXTRACT('week' FROM sale_date)
to extract only weekdays you can add this filter
EXTRACT(dow FROM sale_date) in (1,2,3,4,5)
PS: make sure that monday is first day of the week. In some countries sunday is the first day of the week
You can filter on the last 8 weeks in the where clause, then group by week and do conditional aggregation:
select extract(year from sale_date) yyyy, extract(week from saledate) ww,
sum(last_sale_price - lag_last_sale_price) filter(where lag_last_sale_price > last_sale_price) sum_dollars_up,
count(*) filter(where lag_last_sale_price > last_sale_price) cnt_dollars_up
from (
select dp.*,
lag(last_sale_price) over(partition by extract(year from sale_date), extract(week from saledate) order by sale_date) lag_last_sale_price
from daily_price
where symbol = 'AAPL'
and sale_date >= date_trunc('week', current_date) - '8 week'::interval
) dp
group by 1, 2
Notes:
I am asssuming that you don't want to compare the first price of a week to the last price of the previous week; if you do, then just remove the partition by clause from the over() clause of lag()
this dynamically computes the date as of 8 (entire) weeks ago
if there is no price increase during a whole week, the query still gives you a row, with 0 as sum_dollars_up and cnt_dollars_up

ORA-00907 "missing right parenthesis" extract month and year

Having a horrible time with everything today. I am trying to get a list of month, year and then average the order total for each month. I am getting ORA-00907 "missing right parenthesis" and I am not sure why. Again, I very new to this, but the code that I have I referenced from https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm .Thanks in advance.
SELECT EXTRACT (MONTH, YEAR FROM ORDERDATE) "DATE"
AVG (ORDERDATE) "NO. OF ORDERS"
FROM ORDERINFO
GROUP BY EXTRACT (MONTH, YEAR FROM ORDERDATE)
ORDER BY "MONTH" ASC;
The docs you referenced show that only one of the date part specifier can be of the extract function.
For example, extract(month from orderdate) or extract(year from orderdate).
I'm guessing you really want to truncate the orderdate instead. See https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions201.htm.
SELECT trunc(orderdate, 'MONTH') AS "date"
Either:
select
extract(month from orderdate) as year,
extract(year from orderdate) as month,
...
from ...
group by extract(month from orderdate), extract(year from orderdate)
or:
select
to_char(orderdate, 'YYYY-MM') as year_month,
...
from ...
group by to_char(orderdate, 'YYYY-MM')
this will work:
select extract(month from orderdate) "MONTH",
extract(year from orderdate) "YEAR",
from orderdate
group by extract(month from orderdate)
order by extract(month from orderdate) asc;

SELECT SQL data based on date, fill month

I'm selecting year, month and net sales from invoice table. The problem is that if there's no data under specific month, there will be no rows for that month. Can you help me? Net sales should be zero if there is not any data.
SELECT
DATEPART(year, date) as 'year',
DATEPART(month, date) as 'month',
SUM(netsales) as netsales
FROM invoice
WHERE
date >= '2015-01-01'
AND date <= '2016-12-31'
GROUP BY
DATEPART(year, date),
DATEPART(month, date)
Thanks in advance.
You need a calendar table and left join
;with calendar as
(
select cast('2015-01-01' as date) as dates -- start date
union all
select dateadd(mm,1,dates) from cte where dates < '2016-12-31' -- end date
)
SELECT
DATEPART(year, c.dates) as 'year',
DATEPART(month, c.dates) as 'month',
SUM(netsales) as netsales
FROM calendar C left join invoice i on c.dates = cast(i.[date] as date)
GROUP BY
DATEPART(year, date),
DATEPART(month, date)
I have generates dates on the fly using Recursive CTE, but I will always suggest to create a calendar table physically and use it in such queries

SQL - select most 'active' time from db

Very closely related to SQL - Select most 'active' timespan fromdb but different question.
"I have a table of transactions. In this table I store the transaction datetime in UTC. I have a few months of data, about 20,000 transactions a day."
How would change
select datepart(hour, the_column) as [hour], count(*) as total
from t
group by datepart(hour, the_column)
order by total desc
so that I can select the specific year, month, day, hour, minute, and second that was the most 'active'.
To clarify, I'm not looking for which hour or minute of the day was most active. Rather, which moment in time was the most active.
Select
DATEPART(year, the_column) as year
,DATEPART(dayofyear,the_column) as day
,DATEPART(hh, the_column) as hour
,DATEPART(mi,the_column) as minute
,DATEPART(ss, the_column) as second
,count(*) as count from t
Group By
DATEPART(year, the_column)
, DATEPART(dayofyear,the_column)
, DATEPART(hh, the_column)
, DATEPART(mi,the_column)
, DATEPART(ss, the_column)
order by count desc
If minute resolution is enough:
select top 1 cast(the_column as smalldatetime) as moment, count(*) as total
from t
group by cast(the_column as smalldatetime)
order by total desc

Compare Monday's data to previous Mondays in SQL Server

I am trying to figure out how to compare the current day's data to the same data from a week ago, 2 weeks, etc. Let's say I have a table called "Order" with 2 columns:
Order table
-----------
OrderID int identity
OrderDate datetime
If today, is Monday, I would like to be able to compare the number of orders from today to the previous Mondays for an entire year. Is this possible with a single SQL Server query? I'm using SQL 2008 if it makes a difference.
select CAST (OrderDate as date) as [Date], COUNT(*)
from Orders
where OrderDate > DATEADD(YEAR,-1, getdate())
and DATEPART(DW,OrderDate ) = DATEPART(DW,GETDATE())
group by CAST (OrderDate as date)
Try
SELECT [ColumnsYouWant]
FROM [OrderTable]
WHERE datepart(weekday, OrderDate) = datepart(weekday, getdate())
AND OrderDate >= dateadd(yyyy, -1, getdate())
This gives you Monday order counts by week number:
select year(OrderDate) as Year,
DATEPART(WEEK, OrderDate) as Week,
COUNT(*) as MondayOrderCount
from Order
where DATEPART(WEEKDAY, OrderDate) = 2
group by year(OrderDate), DATEPART(WEEK, OrderDate)
order by Year, Week