sql count instances of a field - microsoft sql server management studio - sql

I want a table like below. I have first 2 columns available. I want the count column to have incremental count of values in column name
name marks count
a 23 1
b 43 2
c 54 3
d 64 4
a 12 2
b 3 2
a 4 3

For SQL Server:
SELECT name,
marks,
Row_number()
OVER (
PARTITION BY name
ORDER BY (SELECT 1)) AS [Count]
FROM MyTable
The rows aren't guaranteed to arrive in any particular order unless you have some way of ordering like the results above that you haven't told us about. There's also no way of knowing which order the ROW_NUMBER will be assigned to all those values with the same name - again - if there is a specific order you'd like to use then use that instead of the (SELECT 1) above.

SELECT name,
marks,
count (id),
FROM MyTable
group by name, marks

Related

How to get rows with minimum ID on a multiple columns query

I have a table like this:
Id
Type
multiple columns (a lot)...
1
50
2
50
3
50
4
75
5
75
6
75
I need to get only the rows with the older (min) id as a part of my query. The result should include all the columns of the table, but given that these multiple columns have multiple values, it's not posible to use MIN() and then GROUP BY
I need something like this:
Id
Type
multiple columns (a lot)...
1
50
4
75
I've tried using MIN() function and grouping by but that's not an option cause the rest of the columns have different values and if I use a GROUP BY I'm getting all the rows and not only the ones with the lowest ID's.
Any ideas?
Thanks!
You can use the WITH TIES option in concert with the window function lag() over()
To be clear, this will flag when the value changes
Example
Select top 1 with ties *
From YourTable
Order by case when lag([type],1) over (order by id) = [Type] then 0 else 1 end desc
Results
Id Type
1 50
4 75
Based on Rodrigo's solution, you may have wanted the first [Type] regardless of sequence.
Select top 1 with ties *
From YourTable
Order by row_number() over (partition by [Type] order by ID)
You can add a column that represents the number of dups.
That result will be used to join only with unique rows.
You can use Common table Expression to split the steps
WITH rows_with_index AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY Type) AS row_number,
id,
Type
FROM
<TABLE>
ORDER BY 2
)
SELECT * FROM rows_with_index t
WHERE rows_with_index.row_number = 1;

Get Count Based on Combinations of Values from Second Column

I have a table format like below:
Id Code
1 A
1 B
2 A
3 A
3 C
4 A
4 B
I am trying to get count of code combinations like below:
Code Count
A,B 2 -- Row 1,2 and Row 6,7
A 1 -- Row 3
A,C 1 -- Row 4
I am unable to get the combination result. All I can do is group by but I am not getting count of IDs based in combinations.
You need to aggregate the rows, somehow, and do that twice. The code looks something like this:
select codes, count(*) as num_ids
from (select id, group_concat(code order by code) as codes
from t
group by id
) id
group by code;
group_concat() might be spelled listagg() or string_agg() depending on the database.
In SQL Server, use string_agg():
select codes, count(*) as num_ids
from (select id, string_agg(code, ',') within group (order by code) as codes
from t
group by id
) id
group by code;

SQL Separating Distinct Values using single column

Does anyone happen to know a way of basically taking the 'Distinct' command but only using it on a single column. For lack of example, something similar to this:
Select (Distinct ID), Name, Term from Table
So it would get rid of row with duplicate ID's but still use the other column information. I would use distinct on the full query but the rows are all different due to certain columns data set. And I would need to output only the top most term between the two duplicates:
ID Name Term
1 Suzy A
1 Suzy B
2 John A
2 John B
3 Pete A
4 Carl A
5 Sally B
Any suggestions would be helpful.
select t.Id, t.Name, t.Term
from (select distinct ID from Table order by id, term) t
You can use row number for this
Select ID, Name, Term from(
Select ID, Name, Term, ROW_NUMBER ( )
OVER ( PARTITION BY ID order by Name) as rn from Table
Where rn = 1)
as tbl
Order by determines the order from which the first row will be picked.

Grouping by number of occurrences of a repeatable value in Oracle SQL

Lets assume we have a table like this.
id name value
1 x 12
2 x 23
3 y 47
4 x 18
5 y 29
6 z 45
7 y 67
Doing a normal group by name would yield us
select name,count(*) from table group by name;
name count(*)
x 3
y 3
z 1
I want to get the reverse.. ie. grouping the number of names that occur a set number of times. I want my output to be
count number of elements occuring count times
1 1
3 2
Is it possible to do this using just a single query? Another way is to use a temp table but I dont want to do that.
Thanks
You need one more group by:
select cnt, count(*), min(name), max(name)
from (select name, count(*) as cnt
from table
group by name
) n
group by cnt
order by 1;
I do these types of histogram queries all the time. The min() and max() provide sample data. This is useful to understand outliers and unexpected values.
You can GROUP BY twice, e.g.
with
Names as (
select name as name,
count(1) as cnt
from MyTable
group by name)
select count(1),
cnt
from Names
group by cnt

query for roww returning the first element of a group in db2

Suppose I have a table filled with the data below, what SQL function or query I should use in db2 to retrieve all rows having the FIRST field FLD_A with value A, the FIRST field FLD_A with value B..and so on?
ID FLD_A FLD_B
1 A 10
2 A 20
3 A 30
4 B 10
5 A 20
6 C 30
I am expecting a table like below; I am aware of grouping done by function GROUP BY but how can I limit the query to return the very first of each group?
Essentially I would like to have the information about the very first row where a new value for FLD_A is appearing for the first time?
ID FLD_A FLD_B
1 A 10
4 B 10
6 C 30
Try this it works in sql
SELECT * FROM Table1
WHERE ID IN (SELECT MIN(ID) FROM Table1 GROUP BY FLD_A)
A good way to approach this problem is with window functions and row_number() in particular:
select t.*
from (select t.*,
row_number() over (partition by fld_a order by id) as seqnum
from table1
) t
where seqnum = 1;
(This is assuming that "first" means "minimum id".)
If you use t.*, this will add one extra column to the output. You can just list the columns you want to avoid this.