Distinct SQL Query - sql

I have a SQL Server 2008 database with the following information in a table:
ID Name
-- ----
1 John
2 Jill
3 John
4 Phil
5 Matt
6 Jill
I want to display the unique names in a drop down list. Because of this, I need just one of the IDs associated with the unique name. I know it's dirty. I didn't create this mess. I just need the unique names with one of the ids. How do I write a query that will do that? I know that the following won't work because of the ID field.
SELECT DISTINCT
[ID], [Name]
FROM
MyTable

SELECT MIN(ID) AS ID, [Name]
FROM MyTable
GROUP BY [Name]
This will return the first (i.e. MINimum) ID for each distinct Name

You could also do it with rank over function
SELECT
Id,
Name
FROM
(
SELECT
Id,
[Name],
RANK() OVER (PARTITION BY [Name] Order By Id) As Idx
FROM Test
) A
WHERE Idx = 1
To get understanding about rank over function read this:
http://msdn.microsoft.com/en-us/library/ms176102.aspx

Related

Selecting distinct values from table using two columns

I have following data in the table.
Id Name
1 Abc
2 Abc
3 Xyz
4 Xyz
5 def
6 def
I want following results from the query
Id Name
1 Abc
2 Xyz
3 def
I want to avoid duplicates in the name column.
Any help is greatly appreciated.
Select distinct
id, name
from table A
will not work as ids are having a different values.
Use a group by instead.
select
min(id), [name]
from
tableA
group by [name]
Note that in your example, the ids that corresponds with Xyz are 3 and 4, so getting a 2 next to Xyz is only possible if you break the integrity of the table. If you are just looking for an auto number next to the ids you can do this:
SELECT row_number() OVER (ORDER BY min(id)) id,
name
FROM tableA
group by name
You can get your specific result using:
select row_number() over (order by min(id)) as id, name
from table A
group by name;
Renumbering the rows seems strange, but row_number() will do that.

How to use DISTINCT in nested personal geodatabse SQL in ArcGIS

I have this Statement used in ArcGIS for a personal geodatabse.
It selects the top three records in [MyColumn1], but not if the [MyColumn2] equals an inline variable.
[MyColumn1] in(SELECT TOP 3 ( [MyColumn1] )
FROM MyTable
WHERE [MyColumn2] <> %Variable%
ORDER BY [MyColumn1] DESC)
But I also need to add a DISTINCT function because some times there are repeated values in [MyColumn1] so that 4 records are selected.
How to include DISTINCT in this expression so that ArcCrash and a personal geodatabase can handle it? There is a lot on this subject, but nothing specific to working Arc or at least access.
This doesn't work
[MyColumn1] in(SELECT TOP 3 ( [MyColumn1] )
FROM MyTable
WHERE [MyColumn2] <> %Variable%
ORDER BY [MyColumn1] DESC
DISTINCT [MyColumn1] )
Nor does this
[MyColumn1] in(SELECT TOP 3 ( [MyColumn1] )
FROM MyTable
WHERE [MyColumn2] <> %Variable%
ORDER BY [MyColumn1] DESC
GROUP BY [MyColumn1])
Well since this isn't the full query your select top 3 is going to return 3 records, but if your MyColumn1 has duplicates and the select distinct returns one of those that has duplicate then both of those will be included in the In statement. For Example.
FirstName | LastName
Bob doe
Billy smith
Marie Evans
Bob Lock
if you then do
Select * from table where FirstName in (SELECT DISTINCT TOP 3 FirstName FROM table)
you will get all 4 records because your inner query will return ("Bob", "Billy", "Marie") and since your initial query (Select * from table where FirstName in ("Bob", "Billy", "Marie")) wants records that have those 3 first names, well they all have at least one of those names. the solution here would be this query.
Select Distinct FirstName from table where FirstName in (SELECT DISTINCT TOP 3 FirstName FROM table)
The problem with this is when you do a distinct you need to include all the column names in it so you will cannot get the last name column from this query.
I used ArcGIS tool Delete Identical which deletes the first of multiple, identical records. HA. quite perfect.

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.

SQL Select list of last records with condition

I have the following table
ID Name CodSituation
1 John 1
2 Mary 2
3 Mary 3
4 Mary 4
5 John 5
6 John 2
7 Mary 1
I want to select the Names, ID's and CodSituation for all users where their last entry is CodSituation=2
In these results I will get just the id 6 As Mary's last entry was CodeSituation=4
if more than one users have their latest CodSituation=2 I want them too.
[FINAL EDIT]
After seeing what was posted at the end of this answer I figured out that the user was asking the wrong question:
What they were asking was 'show me everyone who has CodSituation=2' when they meant 'Show me all the users who's last entry in CodSituation field=2'
Here is the correct query for that:
select a.ID, a.Name, a.CodSituation
from table_name a
inner join (
select Name, max(ID) as MaxID
from table_name
group by Name
) b on a.Name = b.Name and a.ID = b.MaxID
where a.CodSituation = 2;
Here is the fiddle for that: http://sqlfiddle.com/#!2/a731d
[END]
[here are the previous queries, for reference]
Looks to me like you just need:
select * from table_name where CodSituation=2
To get all of the people with situation 2
To get only the last entry using mysql:
select * from table_name where CodSituation=2 order by id desc limit 1
To get the last entry using sql-server:
select top 1 * from table_name where CodSituation=2 order by ID desc;
See a working example here:
http://sqlfiddle.com/#!6/022fb/4
[edit]
OP supplied an actual dataset:
select Name from table_name where CodSituation=2 group by Name;
This shows all the unique users with a CodSituation of 2 (with one entry per person)
http://sqlfiddle.com/#!3/be404/2
Can be achieved like this, but may not be the best way to do this
Basically what I am doing is Create a temporary table and add the Name and Maximum row number.
Which then match again that the maximum row number row is associated with CodSituation=2
Create Table #Temp2(Name Varchar(10),RowN int)
;WITH CTE AS (SELECT *,RN=ROW_NUMBER() OVER(PARTITION BY Name ORDER BY ID)
FROM TableName)
insert into #Temp2
SELECT Name,MAX(RN)
FROM CTE
Group By Name
select TT.*
from
(
SELECT *,RN=ROW_NUMBER() OVER(PARTITION BY Name ORDER BY ID)
FROM TableName
)TT
cross apply (
select Name
from #Temp2 TB
where TB.Name=TT.Name and TB.RowN= TT.RN
) Tab
Where CodSituation=2
Fiddle Sample
I found an easier way concatenating fieds and using max solve this problem... Thanks!
SELECT
right(
max(
right(('0000000' + CONVERT(varchar,id) + '-'+ convert(varchar,codsituation)),4)),10),
name
FROM TABLE_NAME
GROUP BY name
HAVING
right(
max(
right(
('0000000' + CONVERT(varchar,id) + '-'+ convert(varchar,codsituation))
,4)),1) = 2
http://sqlfiddle.com/#!3/3dc1c/10

Getting Number of records in oracle

Am trying to fetch the number of records in the table using Count(*) along with my query condition
Sample Table is
Table: STUD_NAME
Id Name
1 Steven
2 smith
2 Ben
1 Willy
My query is
select std.name
from STUD_Name where id='2'
for this it will display the output as "Smith" and "Ben", along with i need the total number of records in the STUD_NAME table.
By right it should display the total records as "4", please help me out to solve this issue and how to form the query in this case
SELECT name,
cnt as total_count
FROM (
SELECT id
name,
count(*) over () as cnt
FROM stud_name
) t
WHERE id = 2
Assuming that id is a numeric column the single quotes around the value 2 are not needed (and are actually harmful due to the implicit data type conversion that happens in the background)
What about:
select
std.name
,(select count(1) from STUD_Name) nrofstds
from STUD_Name std where std.id='2'
select STUD_NAME.name, CNT.count
from STUD_NAME
, (select count(*) COUNT from STUD_NAME) CNT
where id='2'