SQLITE combine select result set - sql

I have a table like this:
|-----------------------------|
|someText | Date | someInteger|
|-----------------------------|
What i want is to select a query like this:
|-----------------------------------|
|someText | Jan | Feb | March | ... |
|-----------------------------------|
Basicaly i want to summ all the someInteger grouped by someText for each single month, aka
Select Sum(someInteger) From TABLE
Where Date = [month]
GroupBy someText
...and then, if possible, i would like to combine all the 12 queries of this into one resulting table for ease of use and possibly some optimisation.

With conditional aggregation (assuming that all the dates are in the same year):
select
someText,
sum(case when strftime('%m', date) = '01' then someInteger end) Jan,
sum(case when strftime('%m', date) = '02' then someInteger end) Feb,
sum(case when strftime('%m', date) = '03' then someInteger end) Mar,
...................................................................
from tablename
group by someText
See the demo.

How about group by?
Select strftime('%y-%m', date) as yyyymm,
sum(someInteger)
from t
group by strftime('%y-%m', date);

Related

How to count rows matching a filter in aggregate operations

Sorry for the not punctual title, this is the best I succeeded to obtain.
I have a table like this:
date | type | qty
2018-03-21 03:30:00 | A | 3
2018-03-22 03:30:00 | A | 3
2018-03-22 04:57:00 | A | 1
2018-03-22 05:18:00 | B | 3
I do some aggregations on this table, e.g. sum of qty over day or over month.
In the same query I need to count how many rows are of type B, while retrieving the total qty on that day.
So,
select sum(qty), date_trunc('day', date) ... group by date_trunc('day', date);
Now, what I need to do next is to count how many rows are of type B. So the expected result is
day | Bcount | totqty
2018-03-21 | 0 | 3
2018-03-22 | 1 | 7
I thought to use partitions but I'm not sure how to use them in this specific case.
Edit: thank you all, guys, for your answers. This was soooooooo easy 🙄
Since 9.4 release we can replace the CASE WHEN clauses in these aggregate functions by the new FILTER clause, use below query:
select date_trunc('day', date) AS Day,
Count(TYPE) filter (where Type = 'B') AS BCount,
Sum(qty) AS TotalQty
FROM Table1 group by date_trunc('day', date);
For Demo Follow the link:
http://sqlfiddle.com/#!17/a5203/14
Until Postgres 9.4 release, if you wanted to count a few sets of records when executing an aggregate function, you had to use a CASE WHEN.
Like This:
SELECT date_trunc('day', date) AS Day,
SUM(CASE WHEN TYPE = 'B' THEN 1 ELSE 0 END) AS BCount,
Sum(qty) AS TotalQty
FROM Table1 group by date_trunc('day', date);
Use a case expression to do conditional aggregation:
select ...
sum(case when type = 'B' then 1 else 0 end) as Bcount
...
select date_trunc('day', date) ,sum(qty),
SUM (CASE WHEN type = 'B' THEN 1 ELSE 0 END) AS Bcount
FROM Table1
group by date_trunc('day', date);
Demo
http://sqlfiddle.com/#!17/a5203/13

SQL Select Where date in (Jan and March) but not in Feb

I have a table like this in SQL called Balance
+----+-----------+-------+------+
| id | accountId | Date | Type |
+----+-----------+-------+------+
| PK | FK | Date | Int |
+----+-----------+-------+------+
I need to find the accountIds that has balance entries in January and March, but not in Febuary.
Only in 2018 and Type should be 2.
How would I go about writing my sql select statement?
Thanks
Edit:
What's I've done so far:
Selecting rows that either in Jan OR March is not a problem for me.
SELECT AccountId, Date FROM Balance
WHERE Month(Date) in (1,3) AND YEAR(Date) = 2018 AND Type =2
ORDER BY AccountId, Date
But if an AccountId has a single entry, say in January, then this will be included. And that's not what I want.
Only if an Account has entries in both Jan and March, and not in Feb is it interesting.
I suspect Group BY and HAVING are keys here, but I'm unsure how to proceed
I would do this using aggregation:
select b.accountid
from balance b
where date >= '2018-01-01' and date < '2019-01-01'
group by b.accountid
having sum(case when month(date) = 1 then 1 else 0 end) > 0 and -- has january
sum(case when month(date) = 3 then 1 else 0 end) > 0 and -- has march
sum(case when month(date) = 2 then 1 else 0 end) = 0 -- does not have february

PostgreSQL group by and order by

I have a table with a date column. I wanted to get the count of months and display them in the order of months. Months should be displayed as 'Jan', 'Feb' etc. If I use to_char function, the order by happens on text. I can use extract(month from dt), but that will also display month in number format. This is part of a report and month should be displayed in 'Mon' format only.
SELECT to_char(dt,'Mon'), COUNT(*) FROM tb GROUP BY to_char(dt,'Mon') ORDER BY to_char(dt,'Mon');
to_char | count
---------+-------
Dec | 1
Jan | 1
Jul | 2
select month, total
from (
select
extract(month from dt) as month_number,
to_char(dt,'mon') as month,
count(*) as total
from tb
group by 1, 2
) s
order by month_number

Different table layouts

I have a table that looks like this:
|| id | year | userCode | jan | feb | ... ... ... | dec ||
The columns jan - dec holds value (money) data in it. I want it to look like this:
||id | year | month | userCode | value ||
Here's the thing: I can have two values for the same userCode in the same month (and I need them both), so I can't just use SUM. Any ideas?
Thanks in advance!
In SQL Server 2005+ you can easily do this using the UNPIVOT function which transforms data from columns into rows.
The code would be similar to this:
select id, year, month, usercode, value
from yourtable
unpivot
(
value
for month in (Jan, Feb, Mar, Apr, May,
Jun, Jul, Aug, Sep, Oct,
Nov, Dec)
) unpiv
Once the data in the rows, then you can perform any type of aggregation needed.
You can do it with two tables...
One table with Years and Months in it
YearMonths
|| Id | Year | Month | UserCode ||
YearMonthsValues
|| Id | YearMonthId | Value ||
You can do this with union all:
select year, month, userCode, jan, 'jan' as which as value from t union all
select year, month, userCode, feb, 'feb' as which as value from t union all
. . .
select year, month, userCode, dec, 'dec' as which as value from t
I added an extra column which so you would know where the data came from.

select sum of values: grouped by sign

I have a simple SQL table of the following format:
date | value
============
2010-01-01 | -54
2010-01-02 | 134
2010-01-03 | 73
With the following two SQL queries I can select the sum of values and distinguish between the sum of positive values and the sum of negative values.
SELECT YEAR(date), SUM(value) FROM table WHERE value > 0 GROUP BY YEAR(date)
SELECT YEAR(date), SUM(value) FROM table WHERE value < 0 GROUP BY YEAR(date)
Is there a way to do this in a single SQL query?
Thanks in advance!
Not tested (don't know if the case can be put within a SUM instruction), but the CASE instruction could be of help:
SELECT
YEAR(date),
SUM(CASE WHEN value > 0 THEN value ELSE 0 END) as positives_sum,
SUM(CASE WHEN value < 0 THEN value ELSE 0 END) as negatives_sum
FROM
table
GROUP BY
YEAR(date)
Many databases have a SIGN() function
SELECT YEAR(date),
SUM(value)
FROM table
GROUP BY YEAR(date),
SIGN(value)