SQL Sum amount for column with unique values - sql

Update
Realised I was doing it correctly. The reason why I had the issue was because I didn't realise my data for Col1 wasn't as expected, having some Col1 that associates with multiple Col0 (It was supposed to be Col1:Col0 1:1 relationship. That's why the confusion of it's not working as intended.
Original Question
I'm using SQL query to sum a column for total revenue of distinct values in one of the columns, and return a table with combining with other attributes.
Here's my table:
Col 0 Col1 Col2(unique) Revenue
X 1 A 10
X 1 B 20
X 1 C 0
X 2 D 5
X 2 E 8
Y 3 F 3
Y 3 G 0
Y 3 H 50
Desired output:
Col0 Col1 Revenue
X 1 30
X 2 13
Y 3 53
I tried:
WITH
rev_calc AS (
SELECT
Col0,
Col1,
Col2, ##this is for further steps to combine other tables for mapping after this
SUM(Revenue) AS total_revenue, ##total rev by Col1
FROM table_input
GROUP BY Col1, Col0, Col2 ##Have to group by Col0 and Col2 too as it raised error because of 'list expression'
)
SELECT DISTINCT
table2.mappedOfCol0,
rev_calc.Col1,
rev_calc.Col2,
rev_calc.total_revenue,
FROM another_table AS table2
LEFT JOIN rev_calc
ON rev_calc.Col0 = table2.mappedOfCol0
But getting actual output with multiple rows of revenues under a specific Col1.
For example, when i filter by Col1 = 1 in the output table, I get a list of different revenue amount still:
Col1 total_revenue
1 10
1 20
1 0
I thought the GROUP BY should have sum up the revenue by distinctly under Col1. What did I miss out here? I also tried querying first FROM (SELECT DISTINCT Col1....) way but the sum(revenue) is producing a list of different revenue as well
Newbie to SQL here, appreciate if anyone can share any insights here. Thanks.

Don't you just want aggregation?
select col0, col1, sum(revenue) as revenue
from mytable
group by col0, col1
I don't understand what you are trying to do with col2 in the query. This produces the result you want for the data you showed, that contains a single table.

As per explanation you provided, I think your requirement is aggregate revenue of selective records that map with another table based on Col2 values. If that is the case then you may try following query.
WITH
rev_calc AS (
SELECT
distinct(Col2) as Col2
From table_input
LEFT JOIN another_table
ON another_table.Col2 = table_input.Col2
)
SELECT
Col0,
Col1,
SUM(Revenue) AS total_revenue
FROM table_input
WHERE Col2 in (select Col2 from rev_calc)
GROUP BY Col0, Col1;

Related

SQL HAVING COUNT WITH TWO COLUMNS

I have the following tableA
COL1 COL2 COL3
A 1 10-1-2019
B 4 13-4-2019
A 1 13-4-2019
A 1 10-1-2019
A 1 10-1-2019
C 3 20-4-2020
A 1 13-4-2019
I this is the sql code i wish to write but the count do not accept two elements :
select COL1,COL2,COL3
from TableA
group by COL1,COL2,COL3,
HAVING COUNT(COL1,COL2) > 2
And only the result A 1 10-1-2019 should appear because it is the only one that have the pair COL1 COL3 with more than 2 results(in this case three times). The pair COL1 /COL3 is something like a composed primary key
How can i achieve this ?
My database is Sybase ASE
Thanks in advance.
I think this does what you want:
select COL1, COL2, COL3
from TableA
group by COL1, COL2, COL3,
HAVING COUNT(*) > 2;
Perhaps you have a bad example. But I don't see why you think you need to exclude col2.

SQL DISTINCT based on a single column, but keep all columns as output

--mytable
col1 col2 col3
1 A red
2 A green
3 B purple
4 C blue
Let's call the table above mytable. I want to select only distinct values from col2:
SELECT DISTINCT
col2
FROM
mytable
When I do this the output looks like this, which is expected:
col2
A
B
C
but how do I perform the same type of query, yet keep all columns? The output would look like below. In essence I'm going through mytable looking at col2, and when there's multiple occurrences of col2 I'm only keeping the first row.
col1 col2 col3
1 A red
3 B purple
4 C blue
Do SQL functions (eg DISTINCT) have arguments I could set? I could imagine it to be something like KeepAllColumns = TRUE for this DISTINCT function? Or do I need to perform JOINs to get what I want?
You can use window functions, particularly row_number():
select t.*
from (select t.*, row_number() over (partition by col2 order by col2) as seqnum
from mytable t
) t
where seqnum = 1;
row_number() enumerates the rows, starting with "1". You can control whether you get the oldest, earliest, biggest, smallest . . .
You can use the QUALIFY clause in Teradata:
SELECT col1, col2, col3
FROM mytable
QUALIFY ROW_NUMBER() OVER(PARTITION BY col2 ORDER BY col2) = 1 -- Get 1st row per group
If you want to change the ordering for how to determine which col2 row to get, just change the expression in the ORDER BY.
With NOT EXISTS:
select m.* from mytable m
where not exists (
select 1 from mytable
where col2 = m.col2 and col1 < m.col1
)
This code will return the rows for which there is not another row with the same col2 and a smaller value in col1.

Select (show) only different columns from almost similar rows

I have a table with many columns 50+. in order to take decisions I analyze any variant data.
Actually my query:
SELECT maincol, count(maincol) FROM table where (conditions) group by maincol having count(maincol) > 1
then:
SELECT * FROM table where (conditions) and maincol = (previous result)
before consult displays all rows and I have to search one by one
col1, col2, col3, col4, col5, col6, manycolumns..., colN
5 7 1 13 341 9 123
5 7 2 13 341 5 123
I want to get:
col3, col6
1 9
2 5
because it's difficult searching manually column by column.
- N columns could be different
- I don't have access to credentials, then I can't use a programing language to manage results.
- Working on DB2
This will be a little tedious but worth it. This assumes that col1 through coln are all of the same type. If not, cast each to character in the select clause.
The result set will identify the maincol values that occur more than once that also have one or more columns with differing values. The columns that differ will be named.
Select maincol, colname, count(distinct colvalue)
From (
Select maincol, ‘column1’ as colname, col1 as colvalue
from table
Union
Select maincol, ‘column2’ as colname, col2 as colvalue
from table
Union
Select maincol, ‘column3’ as colname, col3 as colvalue
from table
Repeat this pattern for remaining columns
)
Group by maincol, colname
Having count(distinct colvalue) > 1
You could even join the result set from above with the original table to show the entire row including the name of the columns that differ:
Select b.colname, a.*
From table a, Select(
include entire query from above
) as b
Where a.maincol = b.maincol

DB2, SQL query to SUM 2 columns

I need to add to columns in a row.
Table Data
id
Col1
Col2
1
10
20
2
11
20
3
12
20
Result expected
id
Sum
1
30
2
31
3
32
I tried sum(col1 + col2), but that gives the sum of all the columns together.
sum() is a aggregating function (one that give a single result for a group of rows), not a algebraic one: You want the addition (the mathematical sum) of the two columns:
select id, col1 + col2 as sum
from mytable
we have two type of columns in group clause (Aggregation column and Group column) in this query
select id, col1 + col2 as sum
from mytable
group by id
we have to insert id, col1 and col2 in front of group by, otherwise we get this error
Column 'TEST.COL1' is invalid in the select list because it is not
contained in either an aggregate function or the GROUP BY clause.
if use MAX() aggregation function like this
SELECT
ID,
MAX(COL1+COL2) AS SUM
FROM TEST
GROUP BY ID
we get the result BUT this isn't good idea because the cost of this code 4 times more than
bellow code
SELECT
ID,COL1+COL2 AS SUM
FROM TEST
Try this
select id, col1 + col2 as sum
from mytable
group by id

Create SQL summary using union

I currently have some SQL that is used to create an excel report in the following format:
COL1 COL2 COL3
2 1 8
3 7 9
1 2 4
Now what I am trying to do is sum up the total of these each value and insert it at the bottom using UNION ALL (unless of course there is a better way.)
Now the values for each column are generated already by sums. The concept I can't grasp is how to sum all the values for the final row, if this is even possible.
So the output should look like so:
COL1 COL2 COL3
2 1 8
3 7 9
1 2 4
6 10 21
Thanks!
It looks like you want to add
WITH ROLLUP
to the end of your query
eg:
Select sum(a) as col1, sum(b) as col2
from yourtable
group by something
with rollup
Depending on the full nature of your query, you may prefer to use with cube, which is similar. See http://technet.microsoft.com/en-us/library/ms189305(v=sql.90).aspx
select
col1
,col2
,col3
from tableA
union
select
sum(col1)
,sum(col2)
,sum(col3)
from tableA
order by col1,col2,col3
SELECT COL1, COL2, COL3
FROM SomeTable
UNION ALL
SELECT SUM(COL1), SUM(COL2), SUM(COL3)
FROM SomeTable
note. there is also a ROLLUP clause but I think the above would be a simpler solution in this case
http://technet.microsoft.com/en-us/library/ms189305%28v=sql.90%29.aspx