Printing same rows twice in SQL Server - sql

I'm using this query
SELECT
[SCORECARD_NAME], [SCORE_NAME],
[TOTAL_ROWS], [VALID_PERCENTAGE], [INVALID_ROWS]
FROM
{table_name}
and I'm getting the result twice. I'm not getting why its happening like that
what is the solution for this?

You can use SELECT DISTINCT, or here is an option using a CTE with a window function:
;WITH CTE AS (
SELECT [SCORECARD_NAME], [SCORE_NAME], [TOTAL_ROWS], [VALID_PERCENTAGE],[INVALID_ROWS],
ROW_NUMBER() OVER (PARTITION BY [SCORECARD_NAME]
ORDER BY [SCORECARD_NAME]) AS DuplicateCount
FROM Table_Name
)
SELECT * FROM CTE WHERE DuplicateCount = 1;

In case you want rows with same entries to be displayed once then use distinct:
SELECT DISTINCT
[SCORECARD_NAME], [SCORE_NAME], [TOTAL_ROWS],
[VALID_PERCENTAGE], [INVALID_ROWS]
FROM
{table_name};
Let me know in case of any queries.

Related

sql aggregations

any ideas why this doesn't work?
select [column_name_2], max(count(distinct([column_name_1])))
from [table_name]
group by [column_name_2]
but it works if done like this
select [column_name_2], count(distinct([column_name_1])) as [x]
into #temp_table
from [table_name]
group by [column_name_2]
select max(x)
from #temp_table
Well, that's just the way SQL (the language) is defined to work. When you use GROUP BY, the corresponding SELECT list will produce a row for each group in the result. You're trying to take that result and aggregate twice, once with GROUP BY [column_name_2] and a second time with GROUP BY (), as defined by standard SQL. We can't do that in the same query expression.
The good news is you can break this up into more than one query expression:
WITH cte1 AS (
SELECT count(distinct([column_name_1])) AS cnt
FROM [table_name]
GROUP BY [column_name_2]
)
SELECT MAX(cnt) FROM cte1
;
or use a derived table.
You can even order the initial query result by cnt DESC and limit the result to the first row.
In your case, you may not want just the MAX, but also the other column.
With SQL Server, which you may be using. Note: You should add a database specific tag to the question.
SELECT TOP 1 [column_name_2], count(distinct([column_name_1])) AS cnt
FROM [table_name]
GROUP BY [column_name_2]
ORDER BY cnt DESC
;
I don't understand "this doesn't work", what were you expecting and what did you get? Normally you include the GROUP BY value in the result set. So it would be:
select [column_name_2], max(cnt) cnt
from (select [column_name_2], count(distinct [column_name_1]) cnt
from [table_name]
group by [column_name_2]) x
group by [column_name_2]
Ok, after reading your comment I think above is what you are looking for.
SELECT [column_name_two]
, max(x) x
FROM (
SELECT [column_name_two]
, COUNT(DISTINCT [column_name_one]
FROM table_name
GROUP BY [column_name_two]
) AS Tbl
GROUP BY [column_name_two]

best way to get count and distinct count of rows in single query

What is the best way to get count of rows and distinct rows in a single query?
To get distinct count we can use subquery like this:
select count(*) from
(
select distinct * from table
)
I have 15+ columns and have many duplicates rows as well and I want to calculate count of rows as well as distinct count of rows in one query.
More if I use this
select count(*) as Rowcount , count(distinct *) as DistinctCount from table
This will not give accurate results as count(distinct *) doesn't work.
Why don't you just put the subquery inside another query?
select count(*),
(select count(*) from (select distinct * from table))
from table;
create table tbl
(
col int
);
insert into tbl values(1),(2),(1),(3);
select count(*) as distinct_count, sum(sum) as all_count
from (
select count(col) sum from tbl group by col
)A
I think I have understood what you are looking for. You need to use some window function. So, you query should be look like =>
Select COUNT(*) OVER() YourRowcount ,
COUNT(*) OVER(Partition BY YourColumnofGroup) YourDistinctCount --Basic of the distinct count
FROM Yourtable
NEW Update
select top 1
COUNT(*) OVER() YourRowcount,
DENSE_RANK() OVER(ORDER BY YourColumn) YourDistinctCount
FROM Yourtable ORDER BY TT DESC
Note: This code is written sql server. Please check the code and let me know.

How to use count & distinct together for all columns

I am getting error while executing the following query.
SELECT COUNT(distinct *) AS "total unique records" FROM table
Please help me to resolve this issue
Because * is not allowed there. If you want to do this, use a subquery:
select count(*)
from (select distinct t.*
from t
) t;
You probably want :
select count(*)
from (select distinct t.*
from table t
) t;
Use this code too count row
SELECT COUNT(*) AS TotalRecords FROM table
AND use that too count row and return order columns
SELECT COUNT(*) OVER() AS TotalRecords,* FROM table

Performance when using distinct and row_number pagination

I have a SQL something like this:
SELECT A,B,C,FUN(A) AS A FROM someTable
The problem is FUN() is a function which quite slow, so if there are a lot of records in someTable, there will be a big performance issue.
If we using a pagination, we can resolve this issue, we do the pagination like this:
SELECT * FROM(
SELECT A,B,C,FUN(A), Row_number()OVER( ORDER BY B ASC) AS rownum FROM someTable
)T WHERE T.rownum >=1 AND T.rownum<20
In this script, the FUN() will only execute 20 times so the performance is OK.
But we need use alias to order by, so we can't write rownum inline, have to move to sub query or CTE, we chose CTE and it looks like this:
;WITH CTE AS (
SELECT A,B AS alias,C,FUN(A) FROM someTable
)
SELECT * FROM(
SELECT *,Row_number()OVER( ORDER BY alias ASC) AS rownum FROM CTE
)T WHERE T.rownum >=1 AND T.rownum<20
So far we are going fine, we get pagination to solve performance issue, we solve the alias order problem, but somehow we need to add DISTINCT to the query:
;WITH CTE AS (
SELECT DISTINCT A,B AS alias,C,FUN(A) FROM someTable
)
SELECT * FROM(
SELECT *,Row_number()OVER( ORDER BY alias ASC) AS rownum FROM CTE
)T WHERE T.rownum >=1 AND T.rownum<20
After this, the optimize of this SQL seems gone, the FUN() will execute many times as much as the records count in someTable, we get the performance issue again.
Basically we are blocked at here, is there any suggestions?
The problem is that in order to get distinct values, the database engine must run the fun(a) function on all the records being selected.
If you do the fun(a) only in the final select, the distinct should not effect it, so it should run only on the final 20 records.
I've changed the derived table you've used to another cte (but that's a personal preference - seems to me more tidy not to mix derived tables and ctes):
;WITH CTE1 AS (
SELECT DISTINCT A,B AS alias,C
FROM someTable
),
CTE2 AS
(
SELECT *, ROW_NUMBER() OVER(ORDER BY alias) As RowNum
FROM CTE1
)
SELECT *, FUN(A)
FROM CTE2
WHERE RowNum >= 1
AND RowNum < 20
Please note that since the fun function is not deterministic you might get results that are different from your original query - so before adapting this solution compare the results first.

case in group by in a store procedure

is possible do a case in a group by?
similar to this:
select * from table
GROUP BY
CASE WHEN #Attivita=0 THEN (RANK() OVER (GROUP BY Nome,AccountID,Matricola DESC))
END
thanks
you have to group by all selected (non-aggregated) columns..
so if you select * you will need to group by all of them ...
If instead of group by you mean order by then yes you can..
No: this would make no sense.
You can't
use GROUP BY and SELECT *
use RANK in a subclause
use GROUP BY in the OVER clause
GROUP BY over a ranking function makes no sense
What are you trying to do, with input/output and schema please.
Edit, based on gaby's answer
select
*
from
(
SELECT
*, RANK() OVER (GROUP BY Nome,AccountID,Matricola DESC) as bar
from
table
) foo
ORDER BY
CASE WHEN #Attivita=0 THEN bar END