I want to use DISTINCT and TOP in the same query. I tried
SELECT DISTINCT TOP 10 * FROM TableA
but I still have a duplicate personID, so I tought to do:
SELECT DISTINCT (personID) TOP 10 * FROM TableA
But here the syntax is wrong. How do I do it correctly?
You're using a SELECT * which is pulling in all records. If you want to use a true DISTINCT only list out the column you want to receive distinct values of. If you have multiple columns then all those columns combined make up one distinct record.
SELECT distinct TOP 10 personID
FROM TableA
Note that without an ORDER BY this will return the first 10 records in no particular order. The results could be different each time you run the query.
You seem to want 10 random records for different persons. Try this:
select t.*
from (select t.*,
row_number() over (partition by personid order by (select NULL)) as seqnum
from t
) t
where seqnum = 1
In general, though, when using top you should also be using an order by to specify what you mean by "top".
It works simply if you use query like this:
SELECT DISTINCT TOP 2 name FROM [ATTENDANCE] ;
In the above query, name is the column_name and [ATTENDANCE] is the table_name.
You can also use WHERE with this to make filtering conditions.
select distinct personid from tablea sample 10
This works in teradata
Maybe you can do like this:
SELECT TOP 10 t.* FROM (SELECT distinct personID FROM TableA) t
Few options:
1:
SELECT TOP 10 personID
FROM (SELECT distinct personID FROM TableA)
2:
;with cte as
(SELECT distinct personID FROM TableA)
SELECT top 10 personID FROM cte
3:
;with cte as
(SELECT personID,row_count=row_number() over (partition by personID order by personID)
FROM TableA
) SELECT top 10 personID FROM cte where row_count=1
I see this is an old question, but I can suggest a more elegant solution:
SELECT personDetails.*
FROM
(
SELECT TOP (10)
personID
personID
FROM TableA
GROUP BY personID --> use this instead of distinct
) AS distinctIds
OUTER APPLY
(
SELECT TOP (1) * --> fetch only one result matching personID
FROM TableA
WHERE TableA.personId = distinctIds.personID
) AS personDetails
You can use GROUP BY instead of DISTINCT, and you can use OUTER APPLY with TOP(1) to fetch only one matching result.
The Matt Busche answer is correct based on the post title.
But if, as it seems from your code examples, your problem is to have all the record fields from the distinct top 10 personID, you can use that as a subquery:
SELECT TableA.*
FROM TableA
INNER JOIN (SELECT DISTINCT TOP 10 personID FROM TableA) AS B
ON TableA.ID = B.ID
SELECT DISTINCT ta.personid FROM (SELECT TOP 10 * FROM TableA) ta
ta is object of subquery and using ta object we can distinct the values
i fixed it i did
select distinct personid from (SELECT TOP 10 * FROM TableA)
If the goal is to select the top 1 record of every personID, then use
select * from TableA group by personid
Since you are doing a "group by", it will return every column, but will ignore (not display) any additional rows with the same personId
Related
I have a table as follow
ID
ORDERNO
1
123
1
123
2
456
2
456
During every select query done via application using JDBC, only the grouped records based on ORDERNO should be picked.
That means, for example, during first select query only details related to ID = 1, but we cannot specify the ID number in where clause because we do not know how many number of IDs will be there in future. So the query should yield only one set of records; application will delete those records after picking, hence next select query will result in picking other set of records. How to achieve it?
You can use TOP WITH TIES for this
SELECT TOP (1) WITH TIES
t.ID,
t.ORDERNO
FROM YourTable t
ORDER BY
t.ID;
If you want to select and delete at the same time you could delete using an OUTPUT clause
WITH cte AS (
SELECT TOP (1) WITH TIES
t.ID,
t.ORDERNO
FROM YourTable t
ORDER BY
t.ID
)
DELETE cte
OUTPUT deleted.*;
As one option you could select on the MIN(ID) like:
SELECT *
FROM yourtable
WHERE ID = (SELECT MIN(ID) FROM yourtable);
You could also use window functions to do this:
SELECT ID, ORDERNO
FROM
(
SELECT ID, ORDERNO
DENSE_RANK() OVER (ORDER BY ID ASC) AS dr
FROM yourtable
)dt
WHERE dr = 1;
order your rows and select top n number of rows that you want :
select top (1) with ties ID, ORDERNO
from tablename
order by ID asc
I have thousands of groups in a table, something like :
1..
1..
2..
2..
2..
2..
3..
3..
.
.
.
10000..
10000..
How can i make a select that give me the Top 3 groups each time.
I Want something like select Top 3 from rows , but it have to return the first three groups not the first three rows.
You can try this :
;with cte as (
select distinct groupId from mytable order by groupid
)
select * from mytable where TheGroupId in (select top 3 groupdid from cte)
You can use DENSE_RANK to assign a number to each group. All members of the same group will have the same number. Then in an outer query, select top 3 groups:
SELECT *
FROM (SELECT *, DENSE_RANK() OVER (ORDER BY id) AS rnk
FROM mytable ) t
WHERE t.rnk <= 3
The above query assumes that id is the column used to group records together.
SQL Fiddle Demo
Use Ranking function Row_Number() :
SELECT *
FROM (SELECT *,
Row_number()
OVER(
partition BY GroupId
ORDER BY GroupId) AS [rn]
FROM YourTable) t
WHERE rn <= 3
Check this MSDN doc for details of all ranking functions.
There is a sql TOP statement that does this
SELECT TOP number|percent column_name(s) FROM table_name;
a description of what it does and how it is used in alternative sql statements for example for mysql and ms access can be found here: http://www.w3schools.com/sql/sql_top.asp
My bad i misread your question, this will return the top rows not groups, could you explain what you are trying to do in more detail?
SELECT *
FROM
(SELECT *
,ROW_NUMBER() OVER (PARTITION BY [Group] ORDER BY [Group] ASC)rn
FROM TableName
)A
WHERE rn <= 3
I want to skip first 5 records and then select 10 records
I have a column email in table user. Here I am trying to select top 10 unique rows from table user using this query
select DISTINCT TOP 10 email from user
Now I am trying to select top 10 unique rows from table skipping the first 5 records
select DISTINCT SKIP 5 TOP 10 email from user
which is not done and return error.. can anyone help me
SELECT A.NAME FROM
(SELECT distinct RANK() OVER(ORDER BY NAME) RNK,NAME FROM USERS) A
WHERE A.RNK>4 AND A.RNK<16
Using LIMIT will not guarantee you that you will get top rows with proper order.
If you use ANALYTIC functions, it will give you proper results.
SQL_LIVE_DEMO
Here is one way to do it. I like to use Common Table Expressions for some things like this because it makes the query easy to understand, although this isn't particularly complicated.
WITH CTE AS
(
Select Distinct Email From User
)
,
CTE1 AS
(
Select Email, ROW_NUMBER() over (ORDER BY Email) AS RowNumber
From CTE
)
Select Top 10 * From CTE1 Where RowNumber > 5
with t2 as
(
select t1.*,
row_number() over (order by id) rn
from
(select email, max(id) as id from [user] group by email) as t1
)
select * from t2 where rn between 5 and 10
How about this:
SELECT *
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY email) AS row
FROM user ) a
WHERE row > 5 and row <= 10
I think you are using SKIP incorrectly, it should be part of the ORDER BY clause.
SELECT DISTINCT TOP(10) Email FROM TableName WHERE Email not in (SELECT TOP(5) Email From TableName)
You can try this code, in this query fetch distinct 10 email ids skip 5 records as you say in this question.
I have a table, myTable that has two fields in it ID and patientID. The same patientID can be in the table more than once with a different ID. How can I make sure that I get only ONE instance of every patientID.?
EDIT: I know this isn't perfect design, but I need to get some info out of the database and today and then fix it later.
You could use a CTE with ROW_NUMBER function:
WITH CTE AS(
SELECT myTable.*
, RN = ROW_NUMBER()OVER(PARTITION BY patientID ORDER BY ID)
FROM myTable
)
SELECT * FROM CTE
WHERE RN = 1
It sounds like you're looking for DISTINCT:
SELECT DISTINCT patientID FROM myTable
you can get the same "effect" with GROUP BY:
SELECT patientID FROM myTable GROUP BY patientID
The simple way would be to add LIMIT 1 to the end of your query. This will ensure only a single row is returned in the result set.
WITH CTE AS
(
SELECT tableName.*,ROW_NUMBER() OVER(PARTITION BY patientID ORDER BY patientID) As 'Position' FROM tableName
)
SELECT * FROM CTE
WHERE
Position = 1
I have the following table:
memberid
2
2
3
4
3
...and I want the following result:
memberid count
2 2
3 1 ---Edit by gbn: do you mean 2?
4 1
I was attempting to use:
SELECT MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
...but now I want find which record which has maximum count. IE:
memberid count
2 2
SELECT memberid, COUNT(*) FROM TheTable GROUP BY memberid
Although, it won't work for your desired output because you have "memberid = 3" twice.
Edit: After late update to question...
SELECT TOP 1 WITH TIES --WITH TIES will pick up "joint top".
memberid, COUNT(*)
FROM
TheTable
GROUP BY
memberid
ORDER BY
COUNT(*) DESC
SELECT MemberID, COUNT(MemberID) FROM YourTable GROUP BY MemberID
What if there is a tie (or more) for the max? Do you want to display one or all?
This is how I would do this
SELECT memberid, COUNT(1)
FROM members
GROUP BY memberid
HAVING COUNT(1) = (
SELECT MAX(result.mem_count)
FROM (
SELECT memberid, COUNT(1) as mem_count
FROM members
GROUP BY memberid
) as result
)
I would love to see a more efficient approach though.
Do it like this:
SELECT memberid, COUNT(memberid) AS [count] FROM [Table] GROUP BY memberid
This should do the trick with no subselects required:
select top 1 memberid, COUNT(*) as counted
from members
group by memberid
order by counted desc
Can be done quite easy:
SELECT TOP 1 MemberId, COUNT(*) FROM YourTable GROUP BY MemberId ORDER By 2 DESC
I believe the original poster requested 2 result sets.
The only way I know of to get this (in SQL Server) is to dump the original records into a temp table and then do a SELECT and MAX on that. I do welcome an answer that requires less code!
-- Select records into a temp table
SELECT
Table1.MemberId
,CNT = COUNT(*)
INTO #Temp
FROM YourTable AS Table1
GROUP BY Table1.MemberId
ORDER BY Table1.MemberId
-- Get original records
SELECT * FROM #Temp
-- Get max. count record(s)
SELECT
Table1.MemberId
,Table1.CNT
FROM #Temp AS Table1
INNER JOIN (
SELECT CNT = MAX(CNT)
FROM #Temp
) AS Table2 ON Table2.CNT = Table1.CNT
-- Cleanup
DROP TABLE #Temp
How about this query:
SELECT TOP 1 MemberID,
COUNT(MemberID)
FROM YourTable
GROUP BY MemberID
ORDER by count(MemberID) desc
SELECT count(column_name)
FROM your_table;
You need to use a subselect:
SELECT MemberID, MAX(Count) FROM
(SELECT MemberID, COUNT(MemberID) Count FROM YourTable GROUP BY MemberID)
GROUP BY MemberID
The second group by is needed to return both, the count and the MemberID.