Group by week using SQL Server 2008 - sql

I have a table and I want to display the data by week in columns. I have done for a week but cannot do to a all weeks in a month.
In my table I want to group the data by id per week and sum it
My sample data is here: SqlFiddle
Sample o/p
121212 1212 7646 45647

Check this
SELECT month
,SUM(CASE WHEN day between 1 and 7 then Value END) as WEEK_1_VAL
,SUM(CASE WHEN day between 8 and 14 then Value END) as WEEK_2_VAL
,SUM(CASE WHEN day between 15 and 21 then Value END) as WEEK_3_VAL
,SUM(CASE WHEN day between 22 and 28 then Value END) as WEEK_4_VAL
,SUM(CASE WHEN day between 29 and 31 then Value END) as WEEK_5_VAL
FROM sample GROUP BY month
;
Output
month WEEK_1_VAL WEEK_2_VAL WEEK_3_VAL WEEK_4_VAL WEEK_5_VAL
12 8 13 1 119.78 11.89

Do a query where you group by DATEPART(week, ...), which would produce one row per week, and then PIVOT that query to make the rows into columns.

Related

How to get data from date

Hi I would like to get data from date for users. I ve got a table with all months but i would like to get how much they earn on month
user
month
money
1
january
10
2
january
1
1
april
100
2
april
1000
1
march
0
2
march
1
And result should be:
user
money_on_april
money_on_march
1
100
0
2
1000
1
3
0
0
Assuming you want a column for every month, or a certain subset of months:
SELECT
user,
SUM(CASE month WHEN 'january' THEN money ELSE 0 END) As money_on_january,
SUM(CASE month WHEN 'february' THEN money ELSE 0 END) As money_on_february,
...
FROM
YourTable
GROUP BY
user
If you only want columns for the months which exist in the table, then you'll need to use dynamic SQL instead.
If you are using MS SQL, Try PIVOT
SELECT * FROM [Your Table]
PIVOT(
SUM([money])
FOR [month] IN ([january],[april],[march])
)pvt

How to calculate the average per day for different years

I am trying to calculate the average number of times apple with an increment of 3 are shown per day in the years of both 2018 and 2017. To do this I am trying to use setNum and exNum that has a difference of 3.
ID Year Text setNum ExNum
-------------------------------------------------
1 2018-01-21 apple 1 3
2 2017-08-03 apple 2 5
3 2018-03-02 banana 1 3
4 2018-05-22 apple 1 3
5 2018-12-12 apple 3 6
6 2017-04-13 apple 3 6
My current query to obtain this is:
SELECT
2017 = avg(case when Year BETWEEN '2017-01-01' AND '2017-12-31' then 1 else 0 end),
2018 = avg(case when Year BETWEEN '2018-01-01' AND '2018-12-31' then 1 else 0 end)
FROM
exampleTable
WHERE
Text LIKE '%apple%'
This currently outputs:
2017 2018
0 0
Note: The original table had a single text column Increment, which had values like 1-3. That is, the 1-3 represented a setNum of 1 and an ExNum of 3.
Your decision to store a numerical increment range as text is not a good one, and ideally you should be storing the two points of the increment in separate columns. That being said, we can do some string olympics to work around this:
SELECT
YEAR(Year) AS Year,
COUNT(CASE WHEN 3 BETWEEN CAST(LEFT(Increment, CHARINDEX('-', Increment)-1) AS int) AND
CAST(RIGHT(Increment, LEN(Increment) - CHARINDEX('-', Increment)) AS int)
THEN 1 END) AS apple_3_cnt
FROM exampleTable
WHERE
TEXT LIKE '%apple%'
GROUP BY
YEAR(year);
Demo
Here I am aggregating by year, and then taking a conditional count of record, for each year, where the apple increment range contains 3. To do this, I separate out the two ends of the increment range, and then convert them to integers.
Edit:
Based on your updated table, we can try a simpler query:
SELECT
YEAR(Year) AS Year,
COUNT(CASE WHEN 3 BETWEEN setNum AND ExNum THEN 1 END) AS apple_3_cnt
FROM exampleTable
WHERE
TEXT LIKE '%apple%'
GROUP BY
YEAR(year);
Try below
SELECT
avg(case when Year BETWEEN '2017-01-01' AND '2017-12-31' then setNum+ExNum end) as 2017
avg(case when Year BETWEEN '2018-01-01' AND '2018-12-31' then setNum+ExNum end) as 2018
FROM
exampleTable
WHERE
Text LIKE '%apple%'
Your query is fine. The only problem is how and to where you assign the results.
Use this syntax instead
SELECT
avg(case when Year BETWEEN '2017-01-01' AND '2017-12-31' then 1 else 0 end) as A2017,
avg(case when Year BETWEEN '2018-01-01' AND '2018-12-31' then 1 else 0 end) as A2018
FROM
exampleTable
WHERE
Text LIKE '%apple%'
Note that you can't use numbers as variable names.

more than one AVG column with diffrent conditions

I have a table as follows:
id year value
1 2012 10
2 2013 7
3 2013 7
4 2014 8
5 2014 10
6 2015 6
7 2011 12
I need to write a query which gives the AVG value of the last 4 years from today. Meaning that if today is 2016 then the AVG is on 2015,2014,2013.
Basicly this could be done with 3 queries:
Select avg(value) as a
from tab
where year=2015
and
Select avg(value) as b
from tab
where year=2014
and
Select avg(value) as c
from tab
where year=2013
The results based on the given values should be:
2013 7
2014 9
2015 6
Since all of them is on the same table... How can I do that in one query (postgresql)?
it should be without a WHERE.
Something like:
Select avg(with condition) as a, avg(with condition) as b, avg(with condition) as c
from tab
You can group by year and constrict to the years you want in your where clause
select avg(value), year
from tab
where year in (2013,2014,2015)
group by year
The query above will give you 3 separate rows. If you prefer a single row then you can use conditional aggregation instead of a group by
select
avg(case when year = 2013 then value end) as avg_2013,
avg(case when year = 2014 then value end) as avg_2014,
avg(case when year = 2015 then value end) as avg_2015,
from tab
where year in (2013,2014,2015)
select
avg(case when year = date_part('year', NOW()) then value end) as avg_2016,
avg(case when year = ((date_part('year', NOW())) - 1 ) then value end) as avg_2015,
avg(case when year = ((date_part('year', NOW())) - 2 ) then value end) as avg_2014,
avg(case when year = ((date_part('year', NOW())) - 3 ) then value end) as avg_2013
from tab

How to subtract result of 2 queries grouped by a field

I have a table in this form:
id year type amount
1 2015 in 10
2 2015 out 5
3 2016 in 20
4 2016 out 1
...
The followin query will give me the sum of the amount of type = 'in' grouped by year:
SELECT year, sum(amount)
FROM table
WHERE type = in
GROUP BY year
How am I going to get the following result?
year sum(in) sum(out) "in-out"
2015 10 5 5
2016 20 1 19
sum(in) is the sum of the 'amount' where type='in'.
Use a CASE statement to handle the values of type.
SELECT year,
SUM(CASE WHEN type = 'in' THEN amount ELSE 0 END) AS sum_in,
SUM(CASE WHEN type = 'out' THEN amount ELSE 0 END) AS sum_out,
SUM(CASE WHEN type = 'in' THEN amount ELSE -amount END) AS in_out
FROM table
GROUP BY year;

SQL Table UPDATE by row with days per month

SQL Server 2005:
I'm attempting to create a table that looks like this:
JAN | FEB | March .......Dec | YTD
Total Volume:
Days in Month:
Gallons per day AVG:
Three rows with description on left, 13 columns (one for each month and year to date total).
I know how to populate the total volume per month. What would I use for days per month and average? I'd like the days per month to show either the complete number of days if it is a past month or current completed days if its the current month.
You are pivoting the data, so you want the results in columns. You can do this by using direct calculation. Here is an example for the first three months:
select 'Days In Month' as col1,
(case when month(getdate()) < 1 then 0
when month(getdate()) = 1 then day(getdate())
else 31
end) as Jan,
(case when month(getdate()) < 2 then 0
when month(getdate()) = 2 then day(getdate())
when year(getdate()) % 4 = 0 then 29
else 28
end) as Feb,
(case when month(getdate()) < 3 then 0
when month(getdate()) = 3 then day(getdate())
else 31
end) as Mar,