Coun(*),distinct and column - sql

How to accomplish like this in sqlserver
select firstname,count(*) from
(select distinct firstname,lastname,amount
from emp)
group by firstname
This works in oracle.

I don't understand what are you trying to do, but your query could be written this way:
SELECT firstname, COUNT(*)
FROM emp
GROUP BY firstname;
Or:
select firstname, count(*)
from
(
select distinct firstname, lastname, amount
from emp
) AS t
group by firstname;
You can also use the DISTINCT keyword inside the COUNT; something like this: COUNT(DISTINCT columnanme) instead.
Or:
select firstname, lastname, amount, COUNT(*)
from emp
group by firstname, lastname, amount;

Here's an example from some stuff where I work that does basically the same thing:
SELECT SYS_CSL, COUNT(SYS_CSL)
FROM (
SELECT SYS_CSL
FROM [VANTAGE_READ].CSL_SERV_RANK
WHERE AGNT_CSL = 0
AND (STOP_DTE_CSL > GETDATE() OR STOP_DTE_CSL IS NULL)
) t1 GROUP BY sys_csl

You need to name the derived table
select firstname, count(*)
from (select distinct firstname,lastname,amount from emp) derived
group by firstname

Related

show extra columns where group has count of 1

Suppose I have a table Students with just 2 columns LastName and FirstName. I know I can get all the LastNames that only have a 1 FirstName with:
select LastName from Students group by LastName having count(*) = 1
But what if I also want to show the FirstName for those rows?
You could filter with a correlated subquery:
select s.*
from students s
where (select count(*) from students s1 where s1.LastName = s.LastName) = 1
Or, if you have a primary column, you can use not exists:
select s.*
from student s
where not exists (
select 1 from students s1 where s1.LastName = s.LastName and s1.id <> s.id
)
This query would take advantage of an index on (id, LastName).
Finally, another common option is to do a window count:
select *
from (select s.*, count(*) over(partition by LastName) cnt from students s) t
where cnt = 1
You could also do
Select * from Students where lastname in (Select lastname from Students group by lastname having count(*) =1)
Just add it to the select:
select s.LastName, min(s.firstname)
from Students s
group by s.LastName
having count(*) = 1;
If only one row matches, then min() returns the value on that row.
You need to get it using any aggregate function that can return the desired value. Min, Max, first_value(), ir string_agg() you may want all names with the lastname in other use case
select LastName,
first_value(firstname) over (order by firstname) firstname,
Min(firstname)
from Students
group by LastName having count(*) = 1
I found another one myself:
with LastNames as (
select LastName from Students group by LastName having count(*) = 1
)
select LastName, FirstName from Students
where LastName in (select LastName from LastNames)

Oracle query: how do I limit the returned records to only those having a count > 1 but show full results?

I need to show all the users who have more than one ID but not return the users who do. I tried group by having but I need to list the IDs and not just count them so could not get that to work for me. I ended up with using a the code below but it returns all the records.
select id,fname,lname,ssn,dob
count(id) over partition by fname,lname,ssn,dob) as cnt
from TABLE
order by cnt desc;
Use a subquery:
select id, fname, lname, ssn, dob
from (select id, fname, lname, ssn, dob,
count(id) over (partition by fname, lname, ssn, dob) as cnt
from TABLE
) t
where cnt >= 2
order by cnt;
WITH CTE (FNAME, LNAME, TALLY) AS
(
SELECT FNAME, LNAME, COUNT(ID) AS TALLY
FROM TABLE
HAVING COUNT(ID) > 1
)
SELECT T.ID, C.FNAME,C.LNAME FROM CTE C
JOIN TABLE T
ON C.FNAME = T.FNAME
AND C.LNAME = T.LNAME

No column was specified for column 1 of 'T1' when using a sub-select with a group by

I have a working query:
SELECT
COUNT(*), ACCOUNT_ID
FROM
CDS_PLAYER
GROUP BY
ACCOUNT_ID
HAVING
COUNT(*) > 1`
Output
No column name Account_ID
----------------------------
'2' '12345'
I'm trying to add names to these accounts (all from the same table) but with no luck. The only query that gets me close is:
SELECT
LASTNAME, FIRSTNAME, COUNT(ACCOUNT_ID) AS NUMBER
FROM
(SELECT
COUNT(*), ACCOUNT_ID
FROM
CDS_PLAYER
GROUP BY
ACCOUNT_ID
HAVING
COUNT(*) > 1) AS T1
GROUP BY
LASTNAME, FIRSTNAME, PLAYER_ID
But I get an error:
No column was specified for column 1 of 'T1'
Like I said VERY NEW AT THIS. My boss of 4 months wanted me to learn and so I'm self taught (books and google). Any help at all to get me where I need to be would be appreciated!
(I'm using Windows Server 2003 and SQL Server 2000)
The error message can be resolved as below
SELECT LASTNAME, FIRSTNAME, COUNT(ACCOUNT_ID) AS NUMBER
FROM
(SELECT COUNT(*) AS Total, ACCOUNT_ID FROM CDS_PLAYER GROUP BY ACCOUNT_ID HAVING
COUNT(*) > 1) AS T1
GROUP BY LASTNAME, FIRSTNAME, PLAYER_ID`
Add as TOTAL after the count(*)
Does this do what you want?
SELECT COUNT(*), ACCOUNT_ID, LASTNAME, FIRSTNAME, PLAYER_ID
FROM CDS_PLAYER
GROUP BY ACCOUNT_ID, LASTNAME, FIRSTNAME, PLAYER_ID
HAVING COUNT(*) > 1;
You should also update your version of SQL Server. It is like 15 years out of date and hasn't been supported in many years. You can download a free version of SQL Server Express from Microsoft.
you want to select the LASTNAME and FIRSTNAME, but havn't it selected in your subselect. You only can access field which are in the resultset.
Solution: Add it to your GROUP BY clause.
ie:
SELECT
LASTNAME, FIRSTNAME, COUNT(ACCOUNT_ID) AS NUMBER
FROM
(SELECT COUNT(*), LASTNAME, FIRSTNAME, ACCOUNT_ID
FROM CDS_PLAYER
GROUP BY ACCOUNT_ID, LASTNAME, FIRSTNAME
HAVING COUNT(*) > 1) AS T1
GROUP BY
LASTNAME, FIRSTNAME, PLAYER_ID

LIMIT on SQL query

How can I LIMIT the results to 10 in the following query?
I use SQLSRV.
SELECT Id, Firstname, Surname FROM Person WHERE Firstname LIKE ?
Use TOP:
SELECT TOP 10 Id, Firstname, Surname FROM Person WHERE Firstname LIKE ?
use
select top(10) Id, Firstname, Surname ....
The answer by kevingessner is certainly the easiest way.
I just thought I would throw some alternatives in for fun.
SET ROWCOUNT 10
SELECT Id, Firstname, Surname FROM Person WHERE Firstname LIKE ?
SET ROWCOUNT 0
Or a more convoluted way:
With q
as
(
Select ROW_NUMBER() Over(Order by Id) as rn,
Id,
Firstname,
Surname
FROM Person WHERE Firstname LIKE ?
)
Select *
From q
where q.rn <= 10

How we can use CTE in subquery in sql server?

How we can use a CTE in a subquery in SQL Server?
like:
SELECT id (I want to use CTE here), name FROM table_name
Just define your CTE on top and access it in the subquery?
WITH YourCTE(blubb) AS
(
SELECT 'Blubb'
)
SELECT id,
(SELECT blubb FROM YourCTE),
name
FROM table_name
It doesn't work:
select id (I want to use CTE here), name from table_name
It's not possible to use CTE in sub queries.
You can realize it as a work around:
CREATE VIEW MyCTEView AS ..here comes your CTE-Statement.
Then you are able to do this:
select id (select id from MyCTEView), name from table_name
Create a view with CTE/ Multiple CTEs with UNION sets of all CTEs
CREATE VIEW [dbo].[_vEmployees]
AS
WITH
TEST_CTE(EmployeeID, FirstName, LastName, City, Country)
AS (
SELECT EmployeeID, FirstName, LastName, City, Country FROM Employees WHERE EmployeeID = 4
),
TEST_CTE2
AS (
SELECT EmployeeID, FirstName, LastName, City, Country FROM Employees WHERE EmployeeID = 7
)
SELECT EmployeeID, FirstName, LastName, City, Country FROM TEST_CTE UNION SELECT * FROM TEST_CTE2
GO
Now, use it into sub query
SELECT * FROM Employees WHERE EmployeeID IN (SELECT EmployeeID FROM _vEmployees)