SQL field default "count(another_field) +1" - sql

I need to create a field COUNT whose default value is the automatically generated count of times NAME has appeared in that table till now, as shown in example below. Since i am adding the field to an existing table, i also need to populate existing rows. How best to go about this please?
ID NAME COUNT
1 peter 1
2 jane 1
3 peter 2
4 peter 3
5 frank 1
6 jane 2
7 peter 4

You would do this when you are querying the table, using the ANSI-standard row-number function:
select id, name, row_number() over (partition by name order by id) as seqnum
from t;

Related

Active Record Sort by 2 conditions

How can I sort by number first and further sort same number names by alphabet?
Example:
Score | Name
-----------
12 John
11 Paul
10 Dave
9 Adam
9 Ben
9 David
Just use the SQL syntax for ordering by multiple columns:
order by Score, Name
Select * from Table Order by Score , Name

Return based on values selected

I really don't know how to phrase the title correctly, so please excuse me if the title is confusing.
Here's the scenario I am facing:
I have a table...assuming it contains the follow rows.
Name | Value
----- | ----
John | 1
Mary | 2
Jack | 3
Jim | 4
Here's the PL/SQL requirement:
If John exists, return John and his value.
If John does not exist, but Mary does, return Mary and her value.
If neither John nor Mary exist, return either Jack or Jim whichever
has the higher value.
I was able to use cursor to traverse the table and test each row, but am wondering if there are other more efficient way.
Thanks!
No need for a cursor and a loop. You can do this in a single query, using a conditional sort and a fetch clause:
select *
from mytable
order by
case name when 'John' then 1 when 'Mary' then 2 else 3 end,
value desc
fetch first row only
Or if you are a pre-12c version of Oracle, where the fetch clause is not available:
select name, value
from (
select t.*,
row_number() over(order by
case name when 'John' then 1 when 'Mary' then 2 else 3 end,
value desc
) rn
from mytable t
) t
where rn = 1

Select records distinct in one column in Postgresql database

I got the following records where different people have the same name:
id name category_id birthdate family_id
1 joe 2 2014-05-01 1
2 jack 3 2013-04-01 2
3 joe 2 1964-05-01 1
4 jack 5 1982-05-01 2
5 emma 1 2014-05-01 1
6 joe 3 2003-07-06 3
Now I need a query which results to the following. I want only each name once per family_id. I need all values of each record afterwards including the id. In case the table gets further rows down the road I need them too. So the result should include all values.
id name category_id birthdate family_id
1 joe 2 2014-05-01 1
2 jack 3 2013-04-01 2
5 emma 1 2014-05-01 1
6 joe 3 2003-07-06 3
I tried it with several approaches (GROUP BY, DISTINCT, DISTINCT ON etc.) but none was working out for me.
When I use a GROUP BY clause (GROUP BY name) I get a ERROR: column "deals.id" must appear in the GROUP BY clause or be used in an aggregate function. But when I put id inside the clause I get all records back.
Same with distinct. There I have to choose all fields on which the result set should be distinct. But I need all values of the record. And because of the primary each record is distinct when i include the id.
I tried it with a sub clause which has filtered all distinct names. I used them in a where clause. But I got all values back including (of course) the not distinct name/family_id records.
Has anybody a helping hand for me?
You might not of specified all of the fields in your group by and if you included id, then that would make the rows unique.
Try something like:
SELECT
name, category_id, birthdate, family_id
FROM family
GROUP BY
name, category_id, birthdate, family_id;
It worked with DISTINCT ON.
The following worked quite well:
SELECT DISTINCT ON (table.name, table.family_id) table.* FROM table;
The only thing I have to check is the ordering. But I wanted to share my solution so far.

SQL - count without group by? I need to use two ids for a join

I thought I could count a column and add it as a column as I can with a sum but I get an error about having to group by / having. An example of what I want...
Initial table...
Global ID Local ID Name Role
100 1 Andy Manager
100 2 Andy Manager
100 1 John Co-Manager
200 1 Andy Co-Manager
200 2 John Manager
200 2 Mike Manager
I then want to add a column that counts the number of Manager in each group / local pairing...
Global ID Local ID Name Role Manager Count
100 1 Andy Manager 1
100 2 Andy Manager 1
100 1 John Co-Manager 0
200 1 Andy Co-Manager 0
200 2 John Manager 2
200 2 Mike Manager 2
I tried just joining the two tables on the global / local ID and then adding a column for count of the Role. The problem is that I get an error about grouping / having by but I don't want to group anything. I just want to add the column and still have the same number of rows. Any way around this?
FYI - for the last two rows, the last column has 2 because John and Mike are on the same group / local ID
It looks like your definition of a group is a unique combination of [global_id, local_id]. If that is the case you do want to group by those two values, and do a count, where the role is Manager. But because you want other columns from the original table, you must do that count within an inline view, and then join back to the original table, like so:
select t.*, v.mgr_in_grp
from tbl t
left join (select global_id, local_id, count(*) as mgr_in_grp
from tbl
where role = 'Manager'
group by global_id, local_id) v
on t.global_id = v.global_id
and t.local_id = v.local_id
Fiddle: http://sqlfiddle.com/#!2/fb3ace/2/0
Notice that there is a difference on row 3, as compared to your expected output.
John, Co-manager at global_id and local_id 100 and 1, respectively, belongs to a pair that has a manager in that combination (Andy, your first row). So the count appears should be 1.

Retrieve highest value from sql table

How can retrieve that data:
Name Title Profit
Peter CEO 2
Robert A.D 3
Michael Vice 5
Peter CEO 4
Robert Admin 5
Robert CEO 13
Adrin Promotion 8
Michael Vice 21
Peter CEO 3
Robert Admin 15
to get this:
Peter........4
Robert.......15
Michael......21
Adrin........8
I want to get the highest profit value from each name.
If there are multiple equal names always take the highest value.
select name,max(profit) from table group by name
Since this type of request almost always follows with "now can I include the title?" - here is a query that gets the highest profit for each name but can include all the other columns without grouping or applying arbitrary aggregates to those other columns:
;WITH x AS
(
SELECT Name, Title, Profit, rn = ROW_NUMBER()
OVER (PARTITION BY Name ORDER BY Profit DESC)
FROM dbo.table
)
SELECT Name, Title, Profit
FROM x
WHERE rn = 1;