SQL remove duplicate rows when counting - sql

I have a select statement using count and since I am counting the rows instead of returning them how do I make sure that I do not get a duplicate value on a column?
For Example
_table_
fName someField
Eric data
Kyle mdata
Eric emdata
Andrew todata
I want the count to be 3 because Eric is duplicated, is there a way to do that? My select is:
Select Count(*) From _table_ INTO :var
Thanks,

SELECT Count(DISTINCT fName) From _table_ INTO :var
It will count number of distinct elements from fName column.

This will do the Job Select Count(distinct fnmae) From _table_ INTO :var

Try SELECT Count(DISTINCT fName) From _table_ INTO :var

You could select the count of DISTINCT first names:
declare #table table (fname varchar(20), someField varchar(20))
insert into #table (fname, someField)
select 'Eric', 'data'
union select 'Kyle', 'mdata'
union select 'Eric', 'emdata'
union select 'Andrew', 'todata'
-- returns 4, because there are 4 rows in the table
select count(*) from #table
-- returns 3, because there are 3 rows with distinct first names
select count(*) from (select distinct fname from #table) firstNames

Related

How to ROWCOUNT_BIG() value with union all

I have the following query in SQL Server. How do I get the number of rows of previous select query as following format?
Sample Query
select ID, Name FROM Branch
UNION ALL
SELECT ROWCOUNT_BIG(), ''
Sample Output
If you use a CTE you can count the rows and union all together:
with cte as (
select ID, [Name]
from dbo.Branch
)
select ID, [Name]
from cte
union all
select count(*) + 1, ''
from cte;
I think you want to see total count of the select statement. you can do this way.
CREATE TABLE #test (id int)
insert into #test(id)
SELECT 1
SELECT id from #test
union all
SELECT rowcount_big()
Note: Here, the ID will be implicitly converted to BIGINT datatype, based on the datatype precedence. Read more
Presumably, you are running this in some sort of application. So why not use ##ROWCOUNT?
select id, name
from . . .;
select ##rowcount_big; -- big if you want a bigint
I don't see value to including the value in the same query. However, if the underlying query is an aggregation query, there might be a way to do this using GROUPING SETS.
Here are two ways. It's better to use a CTE to define the row set so further table inserts don't interfere with the count. Since you're using ROWCOUNT_BIG() these queries use COUNT_BIG() (which also returns bigint) to count the inserted rows. In order to make sure the total always appears as the last row an 'order_num' column was added to the SELECT list and ORDER BY clause.
drop table if exists #tTest;
go
create table #tTest(
ID int not null,
[Name] varchar(10) not null);
insert into #tTest values
(115, 'Joe'),
(116, 'Jon'),
(117, 'Ron');
/* better to use a CTE to define the row set */
with t_cte as (
select *
from #tTest)
select 1 as order_num, ID, [Name]
from t_cte
union all
select 2 as order_num, count_big(*), ''
from t_cte
order by order_num, ID;
/* 2 separate queries could give inconsistent result if table is inserted into */
select 1 as order_num, ID, [Name]
from #tTest
union all
select 2 as order_num, count_big(*), ''
from #tTest
order by order_num, ID;
Both return
order_num ID Name
1 115 Joe
1 116 Jon
1 117 Ron
2 3

count distinct entries by summing values on a new column

how would you do this:
Tim ...
Tim ...
Henry ...
Henry ...
Henry ...
I have a table thatc ontains these names on the first column and I am interested in adding a new column X, that should have:
0.5
0.5
0.333
0.333
0.333
to count the number of distinct entries in the first column if you were to do the sum of the new column. Thank you!
You could use the following:
select name,
1.0 / count(name) over(partition by name) as X
from yourtable
See SQL Fiddle with Demo
Please try:
select
[Name], 1.00/count(*)
from YourTable
group by [Name]
Sample:
declare #testTable table (Name varchar(10))
insert into #testTable
select 'A' UNION ALL
select 'A' UNION ALL
select 'A' UNION ALL
select 'B' UNION ALL
select 'B'
SELECT
[Name], 1.00/count(*)
FROM #testTable
GROUP BY [Name]

How to obtain count of record differences in the same table, where there are distinct and nearly-distinct records

I've a table TABLEA with data as below
field1 field2 field3.......field16
123 10-JAN-12 0.8.......ABC
123 10-JAN-12 0.8.......ABC
.
.
.
123 10-JAN-12 0.7.......ABC
245 11-JAN-12 0.3.......CDE
245 11-JAN-12 0.3.......CDE
245 11-JAN-12 0.3.......XYZ
...
<unique rows>
When I do a
select field1, field2, ...field16
from TABLEA
I obtain M records,and when I do a
select distinct field1, field2...field16
from TABLEA
I obtain M-x records, where M is in the Millions and x is a much smaller #.
I am trying to write SQL to get the x records (eventually, just get the count).
I've tried all Set operator keywords like
select field1...field16
from TABLEA
EXCEPT
select distinct field1..field16
from TABLEA
Or using UNION ALL instead of EXCEPT. But none of them return x, instead they all return 0 rows.
You can select the rows that are not distinct by
SELECT field1, ... , field16
FROM tablea
GROUP BY field1, ... , field16
HAVING count(*) > 1
Edit: Another approach would be to use an analytical function ROW_NUMBER(), partitioning by all your field columns. The first (i.e. distinct) row for a given set of fields has ROW_NUMBER = 1, the second = 2, the third = 3 etc. So you can select the x-rows with WHERE ROW_NUMBER > 1.
CREATE TABLE tablea (
field1 NUMBER, field2 DATE, field3 NUMBER, field16 VARCHAR2(10)
);
INSERT INTO tablea VALUES (123, DATE '2012-01-10', 0.8, 'ABC');
INSERT INTO tablea VALUES (123, DATE '2012-01-10', 0.8, 'ABC');
INSERT INTO tablea VALUES (123, DATE '2012-01-10', 0.7, 'ABC');
INSERT INTO tablea VALUES (245, DATE '2012-01-11', 0.3, 'CDE');
INSERT INTO tablea VALUES (245, DATE '2012-01-11', 0.3, 'CDE');
INSERT INTO tablea VALUES (245, DATE '2012-01-11', 0.3, 'XYZ');
To select the duplicate rows x:
SELECT *
FROM (
SELECT field1, field2, field3, field16,
ROWID AS rid,
ROW_NUMBER() OVER (PARTITION BY
field1, field2, field3, field16 ORDER BY ROWID) as rn
FROM tablea
)
WHERE rn > 1;
123 10.01.2012 0.8 ABC AAAJ6mAAEAAAAExAAB 2
245 11.01.2012 0.3 CDE AAAJ6mAAEAAAAExAAE 2
you will get what you want with your own 'Except' query that you have posted above. But you must include the 'ALL' keyword in your except as 'Except Distinct' is the default. So I have just added the ALL keyword below in your query itself:
select field1...field16
from TABLEA
EXCEPT ALL
select distinct field1..field16
from TABLEA
If you want a count of the records of M-x then make the above query a subquery in the FROM clause of another query and have count in that outer query and you would get the count as shown below:
Select count(*)
From
(
select field1...field16
from TABLEA
EXCEPT ALL
select distinct field1..field16
from TABLEA
) B
Guess this is what you are looking for.
Good luck
You are not going to get a count of a row result that is not in your distinct, if your column choices are the same. Distinct is showing a 'DISTINCT' possibility of all results so doing a union all is just going to repeat it and except is never going to find anything as you are limiting out your rows. What are you trying to even do? Try to count where the distincts are happening? The answer you got from Wolfgang does that already.
declare #Table Table ( personID int identity, person varchar(8));
insert into #Table values ('Brett'),('Brett'),('Brett'),('John'),('John'),('Peter');
-- gives me all results
select person
from #Table
-- gives me distinct results (no repeats)
Select distinct person
from #Table
-- gives me nothing as nothing exists that is distinct that is not in total
select person
from #Table
except
select distinct person
from #Table
-- shows me counts of rows repeated by pivoting on one column and counting resultant rows from that. Having clause adds predicate specific logic to hunt for.
-- in this case duplicates or rows greater than one
Select person, count(*)
from #Table
group by person
having count(*) > 1
EDIT you can get a difference of the distinct from the total if that is what you mean:
with dupes as
(
Select count(*) as cnts, sum(count(*)) over() as TotalDupes
from #Table
group by person
having count(*) > 1 -- dupes are defined by rows repeating
)
, uniques as
(
Select count(*) as cnts, sum(count(*)) over() as TotalUniques
from #Table
group by person
having count(*) = 1 -- non dupes are rows of only a single resulting row
)
select distinct TotalDupes - TotalUniques as DifferenceFromRepeatsToUnqiues
from Dupes, Uniques

Use SQL to query in order except the first record

I have an idea, e.g. I have a table containing name(Ann, Ben, Chris, Tom, John),
I want to query it using sql from letter a first, z last.
But I have a condition that I want to put John in the first record.
select name
from names
order by
case when name = 'John' then 0 else 1 end,
name
(SELECT * FROM atable WHERE username = 'John')
UNION ALL
(SELECT * FROM atable WHERE username <> 'John' ORDER BY username)
Or more general:
(SELECT * FROM atable ORDER BY username DESC LIMIT 1)
UNION ALL
(SELECT * FROM atable WHERE id NOT IN (
SELECT id FROM atable ORDER BY username DESC LIMIT 1)
ORDER BY username)
If you have to avoid the union for some reason, this slower code will also work:
SELECT * FROM atable
ORDER BY
CASE WHEN id IN (SELECT id FROM atable ORDER BY username DESC LIMIT 1)
THEN 0 ELSE 1 END
, username
In SQL-server the syntax is slightly different, the subquery is:
SELECT TOP 1 id FROM atable ORDER BY username DESC
It is simple:
(SELECT Name
FROM Users
WHERE Name = 'John')
UNION ALL
(SELECT *
FROM Users
WHERE Name <> 'John'
ORDER BY Name)
Placing a case statement in the order by clause does not work with select distinct. I find the following more intuitive and works if you also need select distinct.Although it does return an extra column in the result set.
DECLARE #names TABLE
(
Name varchar(20)
)
INSERT INTO #names
SELECT 'Tom'
INSERT INTO #names
SELECT 'John'
INSERT INTO #names
SELECT 'Chris'
INSERT INTO #names
SELECT 'Ann'
INSERT INTO #names
SELECT 'Ben'
select Name, case when Name = 'John' then 1 else 0 end AS IsTopRow
from #names
order by IsTopRow DESC, Name
Results:
Name IsTopRow
John 1
Ann 0
Ben 0
Chris 0
Tom 0

Counting the rows of a column where the value of a different column is 1

I am using a select count distinct to count the number of records in a column. However, I only want to count the records where the value of a different column is 1.
So my table looks a bit like this:
Name------Type
abc---------1
def----------2
ghi----------2
jkl-----------1
mno--------1
and I want the query only to count abc, jkl and mno and thus return '3'.
I wasn't able to do this with the CASE function, because this only seems to work with conditions in the same column.
EDIT: Sorry, I should have added, I want to make a query that counts both types.
So the result should look more like:
1---3
2---2
SELECT COUNT(*)
FROM dbo.[table name]
WHERE [type] = 1;
If you want to return the counts by type:
SELECT [type], COUNT(*)
FROM dbo.[table name]
GROUP BY [type]
ORDER BY [type];
You should avoid using keywords like type as column names - you can avoid a lot of square brackets if you use a more specific, non-reserved word.
I think you'll want (assuming that you wouldn't want to count ('abc',1) twice if it is in your table twice):
select count(distinct name)
from mytable
where type = 1
EDIT: for getting all types
select type, count(distinct name)
from mytable
group by type
order by type
select count(1) from tbl where type = 1
;WITH MyTable (Name, [Type]) AS
(
SELECT 'abc', 1
UNION
SELECT 'def', 2
UNION
SELECT 'ghi', 2
UNION
SELECT 'jkl', 1
UNION
SELECT 'mno', 1
)
SELECT COUNT( DISTINCT Name)
FROM MyTable
WHERE [Type] = 1