SELECT SUM as field - sql

Suppose i have this table
table (a,b,c,d). Datatypes are not important.
I want to do this
select a as a1,b as b1,c as c1,
(select sum(d) from table where a=a1 and b=b1) as total
from table
group by a,b,c
...but I can't find a way (sqldeveloper keeps complaining with "from clause not found".)
Is there a way? Is it possible?

SELECT a as a1,b as b1,c as c1,
(
SELECT SUM(d)
FROM mytable mi
WHERE mi.a = mo.a
AND mi.b= mo.b
) as total
FROM mytable mo
GROUP BY
a, b, c
It's much more simple and efficient to rewrite it as this:
SELECT a AS a1, B AS b1, c AS c1, SUM(SUM(d)) OVER (PARTITION BY a, b) AS total
FROM mytable
GROUP BY
a, b, c
Note the SUM(SUM(d)) here.
The innermost SUM is the aggregate function. It calculates the SUM(d) a-b-c-wise.
The outermost SUM is the analytic function. It sums the precalculated SUM(d)'s a-b-wise, and returns the value along with each row.

Du you mean something like this?
select a as a1,
b as b1,
c as c1,
sum(sum(d)) OVER (PARTITION BY a, b) AS total
from table
group by a,b,c

you can do it with aliases:
SELECT a AS a1, b AS b1, c AS c1,
(SELECT SUM(d)
FROM test_t t_in
WHERE t_in.a = t.a
AND t_in.b = t.b) AS total
FROM test_t t
GROUP BY a, b, c

Related

Avoid duplicate columns select on nested select

In CrateDB is there a way to avoid to re-select the same column in nested SELECT statement, to show the value in the results?
e.i. in the following query, is there any way to avoid re-selecting A and B through the nested SELECT? Ideally would be nice to select just once in the first
SELECT
A,
B,
AB,
A * B * AB AS ABAB,
A / AB::DECIMAL AS AAB,
FROM (
SELECT
A,
B,
(A + B) AS AB,
FROM (
SELECT
(SELECT count(*) FROM schema.table_01 WHERE process_state IN ('State_1')) AS A,
(SELECT count(*) FROM schema.table_01 WHERE process_state IN ('State_2')) AS B,
) alias_for_subquery_01
) alias_for_subquery_02
Thanks

Which window function is faster?

count(*) OVER (PARTITION BY a, b ORDER BY a, b, c) * 10
This produces the same result as:
dense_rank() OVER (PARTITION BY a, b ORDER BY a, b, c) * 10
Used in a query like this:
SELECT
dense_rank() OVER (ORDER BY a, b) ,
a || b,
count(*) OVER (
PARTITION BY a, b
ORDER BY a, b, c
) * 10 ,
a2,
b1,
c1,
cc1,
c2,
FROM
join ....
ORDER BY 1, 6;
I'm happy with my query result.
But should I appreciate one approach over the other and why?
After PARTITION BY a, b there is no point in adding aor b to ORDER BY, like David commented.
So we simplify to:
count(*) OVER (PARTITION BY a, b ORDER BY c) * 10
dense_rank() OVER (PARTITION BY a, b ORDER BY c) * 10
These two only happen to be equivalent while c is UNIQUE. Else they are not.
You'd need to define exactly what the number is supposed to signify, and show your table definition, and the exact query because joins can introduce duplicates and NULL values.
row_numer() or rank() are similar window functions ...
Performance is practically the same for all of them.

Select distinct rows from two fields

I have a table that has millions of records.
So I might have these columns
a, b, c, d
I need to select all the distinct records based on columns a and b.
But I need to select columns a, b, c and d not just a and b.
Can I do this?
edit
Data might be
1,1,frog,green
1,1,frog,brown
2,1,cat,black
2,4,dog,white
so i need;
1,1,frog,green
2,1,cat,black
2,4,dog,white
SQL Server supports Common Table Expression and Window Function. The query below uses ROW_NUMBER() which ranks the record according to group. It sorts by c ASC, d ASC (just play with it).
WITH records
AS
(
SELECT a, b, c, d,
ROW_NUMBER() OVER(PARTITION BY a, b ORDER BY c, d) rn
FROM TableName
)
SELECT a, b, c, d
FROM records
WHERE rn = 1
SQLFiddle Demo
TSQL Ranking Functions
partition by is your man
SELECT a, b, c, d FROM (
SELECT a, b, c, d, ROW_NUMBER() OVER (PARTITION BY a, b ORDER BY a, b) rn
FROM table
) sq
where rn = 1
Please try:
select *
From(
select
row_number() over (partition by a, b order by a, b) RNum,
*
from
YourTable
)x
where RNum=1
Sample
select * From(
select row_number() over (partition by a, b order by a, b) RNum, *
from(
select 1 a, 1 b, 'frog' c, 'green' d union all
select 1 a, 1 b, 'frog' c, 'brown' d union all
select 2 a, 1 b, 'cat' c, 'black' d union all
select 2 a, 4 b, 'dog' c, 'white' d)x
)y
where RNum=1

Select Sum and multiple columns in 1 select statement

Is there a way to select the sum of a column and other columns at the same time in SQL?
Example:
SELECT sum(a) as car,b,c FROM toys
How about:
select sum(a) over(), b, c from toy;
or, if it's required:
select sum(a) over(partition by b), b, c from toy;
try add GROUP BY
SELECT sum(a) as car,b,c FROM toys
GROUP BY b, c
Since you do not give much context, I assume you mean one of the following :
SELECT (SELECT SUM(a) FROM Toys) as 'car', b, c FROM Toys;
or
SELECT SUM(a) as Car, b, c FROM Toys GROUP BY b, c;
SELECT b,
c,
(SELECT sum(a) FROM toys) as 'car'
FROM toys

In SQL in a "group by" expression: how to get the string that occurs most often in a group?

Assume we have the following table:
Id A B
1 10 ABC
2 10 ABC
3 10 FFF
4 20 HHH
As result of a "group by A" expression I want to have the value of the B-Column that occurs most often:
select A, mostoften(B) from table group by A;
A mostoften(B)
10 ABC
20 HHH
How do I achieve this in Oracle 10g?
Remark: in the case of a tie (when there are more than one value that occurs most often) it does not matter which value is selected.
select A, B
from (
select A, B, ROW_NUMBER() OVER (PARTITION BY A ORDER BY C_B DESC) as rn
from (
select A, COUNT (B) as C_B, B
from table
group by A, B
) count_table
) order_table
where rn = 1;
You want the Bs with the MAX of COUNT group by A, B.
Old school solution, it took me some time and some cursing :)
select a,b
from ta ta1
group by a,b
having count(*) = (select max(count(*))
from ta ta2
where ta1.a = ta2.a
group by b)
This problem can be clarified by creating a view for the count in each A & B group:
CREATE VIEW MyTableCounts AS
SELECT A, B, COUNT(*) C
FROM MyTable
GROUP BY A, B;
Now we can do a query that finds the row c1 where the count is greatest. That is, no other row that has the same A has a greater count. Therefore if we try to find a row c2 with a greater count, no match is found.
SELECT c1.A, c1.B
FROM MyTableCounts c1
LEFT OUTER JOIN MyTableCounts c2
ON (c1.A = c2.A AND (c1.C < c2.C OR (c1.C = c2.C AND c1.B < c2.B)))
WHERE c2.A IS NULL
ORDER BY c1.A;
To resolve tied counts (c1.C = c2.C), we use the value of B which we know is unique within a given group of A.
try this (works on SQL Server 2005):
declare #yourtable table (rowid int, a int,b char(3))
insert into #yourtable values (1,10,'ABC')
insert into #yourtable values (2,10,'ABC')
insert into #yourtable values (3,10,'FFF')
insert into #yourtable values (4,20,'HHH')
;WITH YourTableCTE AS
(
SELECT
*, ROW_NUMBER() OVER(partition by A ORDER BY A ASC,CountOfB DESC) AS RowRank
FROM (SELECT
A, B, COUNT(B) AS CountOfB
FROM #yourtable
GROUP BY A,B
) dt
)
SELECT
A,B
FROM YourTableCTE
WHERE RowRank=1
EDIT without CTE...
SELECT
A,B
FROM (SELECT
*, ROW_NUMBER() OVER(partition by A ORDER BY A ASC,CountOfB DESC) AS RowRank
FROM (SELECT
A, B, COUNT(B) AS CountOfB
FROM #yourtable
GROUP BY A,B
) dt
) dt2
WHERE RowRank=1