Transact SQL - How to perform additional operation on a result set - sql-server-2005

I have a simple query:
select id, count(*) n
from mytable
group by id
Is it possible to include also the sum(n) in the same query? So the result would look something like this:
id n
---- -----------
1 12
2 1
3 14
4 1
5 2
6 6
Sum=36

You can use a common table expression to do this:
--
; WITH cte as (SELECT id
,count(*) n
FROM mytable
GROUP BY id)
SELECT id, n FROM cte
UNION ALL
SELECT 'Sum', SUM(n) from cte
You can also use ROLLUP: (this may not be exactly correct syntax)
SELECT id
,count(*) n
FROM mytable
GROUP BY id
WITH ROLLUP

Related

How do i select all columns, plus the result of the sum

I have this select:
"Select * from table" that return:
Id
Value
1
1
1
1
2
10
2
10
My goal is create a sum from each Value group by id like this:
Id
Value
Sum
1
1
2
1
1
2
2
10
20
2
10
20
I Have tried ways like:
SELECT Id,Value, (SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY IDRNC ) FROM Table v;
But the is not grouping by id.
Id
Value
Sum
1
1
1
1
1
1
2
10
10
2
10
10
Aggregation aggregates rows, reducing the number of records in the output. In this case you want to apply the result of a computation to each of your records, task carried out by the corresponding window function.
SELECT table.*, SUM(Value) OVER(PARTITION BY Id) AS sum_
FROM table
Check the demo here.
Your attempt looks correct.
Can you try the below query :
It works for me :
SELECT Id, Value,
(SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY ID) as sum
FROM Table v;
You can do it using inner join to join with selection grouped by id :
select t.*, sum
from _table t
inner join (
select id, sum(Value) as sum
from _table
group by id
) as s on s.id = t.id
You can check it here
Your select is ok if you adjust it just a little:
SELECT Id,Value, (SELECT SUM(Value) FROM Table V2 WHERE V2.Id= V.Id GROUP BY IDRNC ) FROM Table v;
GROUP BY IDRNC is a mistake and should be GROUP BY ID
you should give an alias to a sum column ...
subquery selecting the sum does not have to have self table alias to be compared with outer query that has one (this is not a mistake - works either way)
Test:
WITH
a_table (ID, VALUE) AS
(
Select 1, 1 From Dual Union All
Select 1, 1 From Dual Union All
Select 2, 10 From Dual Union All
Select 2, 10 From Dual
)
SELECT ID, VALUE, (SELECT SUM(VALUE) FROM a_table WHERE ID = v.ID GROUP BY ID) "ID_SUM" FROM a_table v;
ID VALUE ID_SUM
---------- ---------- ----------
1 1 2
1 1 2
2 10 20
2 10 20

Return distinct results that appear more than once

I have the following data:
ID Site
2 NULL
2 32
3 6
4 7
8 12
8 13
9 14
9 14
Result should be:
ID Site
2 NULL
2 32
8 12
8 13
Note that the result find unique combinations of ID and Site that repeat more than once for a given ID.
I did the following query but does not return the result:
select distinct id, site
from Table1
group by id, site
having count(*) > 1
order by id
SELECT
ID,
site
FROM table1
WHERE ID IN (
SELECT ID
FROM (
SELECT ID ,site
FROM table1
GROUP BY ID ,site
) x
GROUP BY ID
HAVING count(*)>1
)
See: DBFIDDLE
The SELECT ID, site FROM table1 GROUP BY ID, site will select the distinct values.
Then, using HAVING count(*) > 1, only the IDs that appear more than once are filtered.
P.S. You should try to avoid using DISTINCT and GROUP BY in one query. It makes life so much more complicated when you do that ... 😉
One way to do it is to do the select distinct in a CTE, then use the count window function to get the desired result:
with u as (
select distinct *
from Table1
), v as (
select *
, count(*) over(partition by ID) as cnt
from u
)
select ID, Site
from v
where cnt > 1;
Fiddle

Add a column with the max value of the group

I want to add an extra column, where the max values of each group (ID) will appear.
Here how the table looks like:
select ID, VALUE from mytable
ID VALUE
1 4
1 1
1 7
2 2
2 5
3 7
3 3
Here is the result I want to get:
ID VALUE max_values
1 4 7
1 1 7
1 7 7
2 2 5
2 5 5
3 7 7
3 3 7
Thank you for your help in advance!
Your previous questions indicate that you are using SQL Server, in which case you can use window functions:
SELECT ID,
Value,
MaxValue = MAX(Value) OVER(PARTITION BY ID)
FROM mytable;
Based on your comment on another answer about first summing value, you may need to use a subquery to actually get this:
SELECT ID,
Date,
Value,
MaxValue = MAX(Value) OVER(PARTITION BY ID)
FROM ( SELECT ID, Date, Value = SUM(Value)
FROM mytable
GROUP BY ID, Date
) AS t;
There is no need to use GROUP BY in subselect.
select ID, VALUE,
(select MAX(VALUE) from mytable where ID = t.ID) as MaxValue
from mytable t
Use this query.
SELECT ID
,value
,(
SELECT MAX(VALUE)
FROM GetMaxValue gmv
WHERE gmv.ID = gmv1.ID
GROUP BY ID
) as max_value
FROM GetMaxValue gmv1
ORDER BY ID
Try it with a sub select and group by, then grab the MAX of this group:
select
ID,
VALUE,
(select MAX(VALUE)
from mytable
group by ID
having ID = t.ID
) as max_values
from mytable t
Edit:
I built a SQL fiddle, which shows that my solution works, but also VDohnal is correct and doesn't need the group by, so I'll upvote his answer.

SQL Server row_number

I have a problem to create a custom rownumber with an alias column. Here are some sample data:
Table question:
id title
-- --------
1 xx
2 xxx
..
Table customerLikeQuestion:
Id QuestionId CustomerId
---------------------------
1 20 xx
2 100 xx
xx
Query:
SELECT q.Id,
(SELECT COUNT(*)
FROM dbo.CustomerLikeQuestion
WHERE (QuestionId = q.Id)) AS LikeCount
FROM dbo.Question AS q
ORDER BY likecount DESC
The previous query shows:
id LikeCount
2136 6
2138 5
2150 5
Now I'd like to put a rownumber to count an incremental order of a row. I tried the following query:
SELECT TOP (100) PERCENT Id,
(SELECT COUNT(*) AS Expr1
FROM dbo.CustomerLikeQuestion
WHERE (QuestionId = q.Id)) AS LikeCount,
row_number() over (order by likecount) as RowNum
FROM dbo.Question AS q
ORDER BY likecount DESC
But it gives me the following error:
invalid column Likecount.
I do know that Over() cannot work with alias, but how can I get around this problem, either with CTE or subquery, I have not yet come up with any idea. please help.
The right result should be like this:
id likecount, rownum
----------------------
xx 6 1
xx 5 2
xx 4 3
.. 0 xx
Try this instead
;WITH LiksCounts
AS
(
SELECT Id,
(SELECT COUNT(*) AS Expr1
FROM dbo.CustomerLikeQuestion
WHERE (QuestionId = q.Id)) AS LikeCount
FROM dbo.Question AS q
GROUP BY Id
)
SELECT TOP(100) *, row_number() over (order by likecount) as RowNum
fROM LiksCounts
ORDER BY RowNum ASC
Live DEMO

sql server select first row from a group

I have table like this:
a b
1 23
1 2
1 7
2 9
2 11
I want to select the first row(order does not matter) from a "GROUP BY a" query , the result should be
a b
1 23
2 9
I am using SQL SERVER 2008 how to write the query for this?
select a,b
from (
select a,b,row_number() over(partition by a order by b desc) as roworder
from myTable
) temp
where roworder = 1
see http://msdn.microsoft.com/en-us/library/ms186734.aspx
If as you indicated, order doesn't matter, any aggregate function on b would be sufficient.
Example Using MIN
SELECT a, b = MIN(b)
FROM YourTable
GROUP BY
a