Calculate sum based on distinct values in other column - sql

I have a table where I want to sum based on distinct values in id column.
Main Table
Pipe separated main file
Id|col1|col2|col3|col4|col5|col6|col7|Dim1|Dim2|Values
r1||||1.2||||sc1|c1|1.2
r4||||||0.98||sc1|c1|0.98
r5|||0.89|||||sc1|c1|0.89
r1||||1.2||||sc2|c1|1.2
r2|||||0.98|||sc2|c1|0.98
r3||||1.22||||sc2|c1|1.22
r4|||||0.98|||sc2|c1|0.98
Output
Pipe separated result
col1|col2|col3|col4|col5|col6|Dim2
0|0|0.89|2.42|1.96|0.98|c1
For columns col1 -col7, I want to do this:
select sum(col1),sum(col2),sum(col3),sum(col4)...sum(col7)
group by dim2 based on distinct values in id.
I could use row_number()over(partition by id) and use the row_number=1, but I can't use subquery. I am looking to do this in just one query.

Related

How can I separate same column values to a variable based on value in another column?

suppose I Have below table
A
B
1
one
2
two
1
three
2
four
1
last
for value in A=1
then I need the output as one;three;last
how can I query this in Oracle's SQL?
If you care whether you get the string "one;three;last" or "three;one;last" or some other combination of the three values, you'd need some additional column to order the results by (a database table is inherently unordered). If there is an id column that you're not showing, for example, that could do that, you'd order by id in the listagg.
If you don't care what order the values appear in the result, you could do something like this
select listagg( b, ';' ) within group (order by a)
from your_table
where a = 1

SQL : select only first row when there is duplicate data in group

How to select only one row data in each different group when I'm using sum with group by?
I would like to remove the second row and show only first row and third row.
This is my query:
SELECT f_provider, SUM(f_rebate_amount) as total_cashback,
DATE(f_match_time) as match_time, f_status
FROM rebate_history
GROUP BY f_provider, f_created_time, f_status

Count only a specific subset of elements in a Postgres DB

I have a table with some identifiers that repeat themselves like
id
-------
djkfgh
kdfjhw
efkujh
dfsggs
djkfgh
djkfgh
efkujh
I also have a list of id's of interest, say ["djkfgh","dfsggs"]. I would like to count only those values that appear in the list, rather than all the distinct values of the column.
Select count(id) from table where id IN(subset);

find unique rows using SQL?

I want to return all the rows from a table which are unique. I.e. if a certain field in two rows contain the same name, that name shouldn't be shown.
Since you want only the uniques names (and not an unique row for every names like you could have with DISTINCT), you have to use a GROUP BY and a HAVING (instead of a WHERE, because your parameter is the result of a function, not a variable) :
SELECT name FROM myTable GROUP BY name HAVING COUNT(name) = 1
SELECT DISTINCT column_name FROM table
If you want the complete rows, then use row_number() or distinct on:
select distinct on (name) t.*
from table t
order by name;

SQL Server Sum multiple rows into one - no temp table

I would like to see a most concise way to do what is outlined in this SO question: Sum values from multiple rows into one row
that is, combine multiple rows while summing a column.
But how to then delete the duplicates. In other words I have data like this:
Person Value
--------------
1 10
1 20
2 15
And I want to sum the values for any duplicates (on the Person col) into a single row and get rid of the other duplicates on the Person value. So my output would be:
Person Value
-------------
1 30
2 15
And I would like to do this without using a temp table. I think that I'll need to use OVER PARTITION BY but just not sure. Just trying to challenge myself in not doing it the temp table way. Working with SQL Server 2008 R2
Simply put, give me a concise stmt getting from my input to my output in the same table. So if my table name is People if I do a select * from People on it before the operation that I am asking in this question I get the first set above and then when I do a select * from People after the operation, I get the second set of data above.
Not sure why not using Temp table but here's one way to avoid it (tho imho this is an overkill):
UPDATE MyTable SET VALUE = (SELECT SUM(Value) FROM MyTable MT WHERE MT.Person = MyTable.Person);
WITH DUP_TABLE AS
(SELECT ROW_NUMBER()
OVER (PARTITION BY Person ORDER BY Person) As ROW_NO
FROM MyTable)
DELETE FROM DUP_TABLE WHERE ROW_NO > 1;
First query updates every duplicate person to the summary value. Second query removes duplicate persons.
Demo: http://sqlfiddle.com/#!3/db7aa/11
All you're asking for is a simple SUM() aggregate function and a GROUP BY
SELECT Person, SUM(Value)
FROM myTable
GROUP BY Person
The SUM() by itself would sum up the values in a column, but when you add a secondary column and GROUP BY it, SQL will show distinct values from the secondary column and perform the aggregate function by those distinct categories.