I have the following data structure, where value1 and value2 - some aggregated values for each segment and date(I can get unaggregated data, if it helps)
date segment value1 value2
--- ------ ------- ------
What do I need is a report,which looks like this:
2015-01-01 2015-01-02
value1 value2 value1 value2
------ ------ ------ ------
segment1 19 5 18 7
segment2 20 5 21 7
for each date in a given period at the same time. How can I do that?
If I understand the question, you want the segment followed by a sum of the columns Value 1 and value 2, if So here is an easy group to do that:
select segment
, sum(Value1) as Value1
, sum(value2) as Value2
From YourTable
group by segment
Related
I currently have a table that looks like this:
date ---- x ---- y ---- z
2020----- 2 ---- 4 ---- 8
2018 ---- 3 ---- 3 ---- 2
2019 ---- 1 ---- 6 ---- 0
I like to rotate this table meaning that the columns become rows like this:
date ---- metric ---- value
2020 ---- x ---- 2
2018 ---- x ---- 3
2019 ---- x ---- 1
2020 ---- y ---- 4
2018 ---- y ---- 3
2019 ---- y ---- 6
2020 ---- z ---- 8
2018 ---- z ---- 2
2019 ---- z ---- 0
If it was in python, I could do it using the pivote() or t() function. However, I am not sure how to do it with SQL. Could you please help me with that?
Thanks!
A canonical method is union all:
select date, 'x' as metric, x as value from t union all
select date, 'y' as metric, y as value from t union all
select date, 'z' as metric, z as value from t;
Some databases support lateral joins, which simplifies this -- and is a bit faster.
SQL noob here. I want to sum two columns separately, using 2 separate where conditions.
ID NAME VALUE1 VALUE2
--- ------- ------- -------
1 Orange 5 30
2 Orange 11 30
3 Orange 7 15
4 Pear 12 12
5 Pear 13 25
6 Pear 4 25
Sum of VALUE1 column where values are > 10
Sum of VALUE2 column where values are > 20
Grouped by NAME
Desired output:
NAME VALUE1 VALUE2
------- ------- -------
Orange 11 60
Pear 25 50
Thanks!
Use conditional aggregation:
select name, sum(case when value1 > 10 then value1 end),
sum(case when value2 > 20 then value2 end)
from t
group by name;
I know this approach is bit tricky and lengthy as well,however this might be helpful in debugging ,if you can try this :
select
value1.name,value1.a,value2.b
from
(select sum(value1)a,name from test where value1 >10 group by name) as value1
join (select sum(value2)b,name from test where value2 >20 group by name) as value2
on value1.name = value2.name
Need suggestions on what would be the best way to normalize the following table:
Earlier, I had a table:
personId year dob column1 column2 column3
-------- ---- --- ------- ------- -------
Here, (personId+year) was the primary key, and columns dob, column1, column2 and column3 had unique values.
Now, according to a new requirement column1, column2 and column3 will be storing multiple values. In a very naive sense, it is supposed to hold values like:
personId year dob column1 column2 column3
-------- ---- ------ ------- ------- -------
1 2018 2.1.20 A1, A2 B1 C1, C2, C3
I simply do not want to normalize it till First Normal Form, but want to break it into more tables, like:
Table 1:
personId year dob
-------- ---- ------
1 2018 2.1.20
Table 2:
personId year column1
-------- ---- ------
1 2018 A1
1 2018 A2
Table 3:
personId year column2
-------- ---- ------
1 2018 B1
Table 4:
personId year column3
-------- ---- ------
1 2018 C1
1 2018 C2
1 2018 C3
Now Table 1 looks fine to me as it still has a PK of (personId+year), but Tables 2-3 don't look very elegant as they lack a primary key.
Are there better ways to achieve this?
You are close. You should introduce a new primary key for the first table and I would recommend primary keys for the others as well:
Table 1:
t1Id personId year dob
1 1 2018 2.1.20
Table 2:
t2Id t1Id column1
1 1 A1
2 1 A2
Table 3:
t3Id t1id column2
1 1 B1
Table 4:
t4Id t1id column3
1 1 C1
2 1 C2
3 1 C3
If ordering is important, you may also want to include a sequential numbering column in all but the first table.
In addition, the data columns in the last three tables should perhaps be ids to their own tables.
Basically I need to generate a frequency table using sql, and I have a sample table like this:
user_id user_label code1 date
------ ----------- ----- ------
1 x a 01-01
1 x a 01-01
1 x a 01-02
1 x b 01-01
1 x c 01-02
1 y a 01-01
2 x a 01-01
etc
The rule to count occurrences is if two rows have the same user_id ,user_label and date ,then repeated codes should only be counted once.
For example, for the first two rows the frequency table should be :
user_id user_label code1 count_code_1
-------- ----------- ----- ------------
1 x a 1
Because even though there are two instances of a, but they happen on the same date so should only be counted once and I need do this for every unique codes in code_1 column
for all combinations of user_id + user_label
After processing the third row , the frequency table should be :
user_id user_label code_1 count_code_1
-------- ----------- ------ ------------
1 x a 2
Since although is the same code ('a') but it happens on a different date (01-02)
In the end, for the sample table given above, the desired result should be
user_id user_label code_1 count_code_1
-------- ----------- ------ -------------
1 x a 2
1 x b 1
1 x c 1
1 y a 1
2 x a 1
What I have so far is
select t.user_id, t.user_label, t.code_1, count(###)
from t
group by t.code_1,t.user_id, t.user_label
The problem is
1. I don't know what to put inside the count 2. I don't know how to incorporate the condition on date in to this query.
Any suggestion, correction would be greatly appreciated.
You seem to want count(distinct date):
select t.user_id, t.user_label, t.code_1,
count(distinct date)
from t
group by t.code_1,t.user_id, t.user_label
I have a little problem when querying data. I have a table that looks like this:
Value1 Value2
--------------------
ABC 123
BCD 123
DCE 123
EFG 123
What I'm hoping to do is, basically only select VALUE1 from this table, however, I'd like to assign an ID to go along with each value...
Desired end result
ID Value1
--------------
1 ABC
2 BCD
3 DCE
4 EFG
Is something like that possible? I'd hope to have the end result to be in alphabetical order and ID's assigned based in ASCENDING order. Also, would hope that this query can be in place even if more VALUE1 values are added in the table (dynamic)
Any ideas?
You can use window function row_number while selecting:
select row_number() over (
order by value1
) as id,
value1
from your_table;