SQL - combination of MIN and COUNT - sql

This is in Oracle database. Say I have the following table A:
column1 column2
id1 a
id2 a
id3 a
id4 b
id5 b
id6 c
So what I want the sql does is:
First count there's three As and two bs and one c, then based on the counts return me the smallest number of these counts, in this case is 1 (because we only have one c)
Can this be achieved somehow by using the combination of MIN and COUNT?

In Oracle you can do this directly; count per group and use MIN on the results to get back one row with the desired value.
select min(count(*))
from tablea
group by column1;

Try this:
SELECT MIN(Count) as MinVal
FROM
(SELECT column2,COUNT(column2) as Count
FROM TableA
GROUP BY column2) T
Explanation:
Inner query select the counts of column2 for each value of column2 in the table. Then with the outer query, the minimum count is selected.

If you are using Oracle 12, you can do this without a subquery:
select count(*) as cnt
from table t
group by cnt
order by cnt asc
fetch first 1 row only;
For those familiar with MySQL or Postgres, fetch first 1 row only is equivalent to limit, and allows you to limit the number of output rows without using a subquery.

This should work for you
SELECT *
FROM(
SELECT Column2, COUNT(Column1)
FROM TableA
GROUP BY Column2
ORDER BY COUNT(Column1))
WHERE Rownum = 1

SELECT MIN(cnt)
FROM (SELECT COUNT(*) AS cnt
FROM my_table
GROUP BY column2)
EDIT:
As ElmoVanKielmo noted, it's somewhat pointless to offer a solution without explaining it.
The inner query groups the data by column2 values, and return the number of rows for each one. The outer query treats these as just a bunch of numbers, and returns the minimal value among them.

Related

how to use group by with offset and fetch rows only on oracle

I want to to make sum of amount of certain rows using offset clause and fetch next rows only and using group by but it gives error, i used the below query
select sum(amount), column1 from table1 where column1 = '000000000' and column2 =0
group by column1 order by transaction_date desc
offset 12 rows
fetch next 12 rows only;
Your query fails as transaction_date, which you are trying to ORDER BY, is not either in the GROUP BY clause or a column alias in the SELECT clause.
You can fix it by fetching the rows first in a sub-query and then aggregating:
SELECT SUM(amount),
column1
FROM (
SELECT amount,
column1
FROM table1
WHERE column1 = '000000000'
AND column2 =0
ORDER BY transaction_date DESC
OFFSET 12 ROWS
FETCH NEXT 12 ROWS ONLY
)
GROUP BY column1;
Your error is this:
order by transaction_date desc
You aggregate your rows such as to get one result row per column1. But for a column1 there can be many different transaction_date, so which one do you want to sort by? You can use by the column1's minimum or maximum transaction_date for instance. E.g.:
order by max(transaction_date) desc
And as there can be ties (multiple column1 with the same maximum transaction_date), you should get your ORDER BY clause deterministic by adding the column1:
order by max(transaction_date) desc, column1
Now that you have the syntax error resolved and a semantic problem, too, there remains another issue: You select only column1 = '000000000'. Then you group by column1. This gives you one result row. Of these one row(s), you skip twelve :-) You'll get no result row with this query.

How to take count of distinct rows which have a specific column with NULL values is all rows

I have a table CodeResult as follows:
Here we can notice that Code 123 alone has a Code2, that has a value in Result. I want to take a count of distinct Codes that has no values at all in Result. Which means, in this example, I should get 2.
I do not want to use group by clause because it will slow down the query.
Below code gives wrong result:
Select count(distinct code) from CodeResult where Result is Null
One method is two levels of aggregation:
select count(*)
from (select code
from t
group by code
having max(result) is null
) c;
A more clever method doesn't use a subquery. It counts the number of distinct codes and then removes the ones that have a result:
select ( count(distinct code) -
count(distinct case when result is not null then code end )
)
from t;
You simply can't avoid a GROUP BY: In all DBMSs I know, the query plan you get from a:
SELECT DISTINCT a,b,c FROM tab; ,
is the same as the one for:
SELECT a,b,c FROM tab GROUP BY a,b,c;
The following query will return each of the Code values for which there are no corresponding non-NULL values in CodeResult:
select distinct Code
from CodeResult as CR
where not exists
( select 42 from CodeResult as iCR where iCR.Code = CR.Code and iCR.CodeResult is not NULL );
Counting the rows is left as an exercise for the reader.

Number of times one row column equals another row's other column in SQL

The confusing question is best asked through an example. Say we have the following result set:
What I want to do is count how many times one number appears from both columns.
So the returning data set might look like:
ID Counted
0 4
1 2
9 1
13 1
My original thought was to do some sort of addition between the counts on both IDs, but I'm not exactly sure how to GROUP them in SQL in a way that is working.
You can do this with a subquery, GROUP BY, and a UNION ALL, like this:
SELECT ID, COUNT(*)
FROM(
SELECT ID1 AS ID FROM MyTable
UNION ALL
SELECT ID2 AS ID FROM MyTable
) source
GROUP BY ID
ORDER BY ID ASC

compare two fields of a single table in oracle sql

I have a table like this, I need to write a sql query to compare and validate the records are in proper order. ex: dhoni is having no1 in column2 like that each players have their own no's , I need to write a code to validate that no player has the same no's assigned for more than one player. and need to check weather the player has his assigned no only.
+-------+-------+
|column1|column2|
+-------+-------+
|dhoni |no1 |
|sachin |no2 |
|dravid |no3 |
|dhoni |no1 |
+-------+-------+
Note:
write a query to validate the table data ex: to check dhoni should always has to get no1 in column2, irrespective of duplicate records and order, like wise need to check for other players also, irrespective of no of data's present in table.. just need to validate the things..
Find one user with more than one no.
select column1 from table group by column1 having count(*) > 1;
Find the same no with more then one user.
select column2 from table group by column2 having count(*) > 1;
Please try:
SELECT
column2, COUNT(*) TotalCount
FROM YourTable
GROUP BY column2
HAVING COUNT(*) > 1
ORDER BY COUNT(*) DESC
where TotalCount returns the count of number assigned multiple times.
or
select * From(
SELECT distinct Column1, Column2, COUNT(*) over (partition by Column2) TotalCount
FROM YourTable
)x
where TotalCount>1

Get row count including column values in sql server

I need to get the row count of a query, and also get the query's columns in one single query. The count should be a part of the result's columns (It should be the same for all rows, since it's the total).
for example, if I do this:
select count(1) from table
I can have the total number of rows.
If I do this:
select a,b,c from table
I'll get the column's values for the query.
What I need is to get the count and the columns values in one query, with a very effective way.
For example:
select Count(1), a,b,c from table
with no group by, since I want the total.
The only way I've found is to do a temp table (using variables), insert the query's result, then count, then returning the join of both. But if the result gets thousands of records, that wouldn't be very efficient.
Any ideas?
#Jim H is almost right, but chooses the wrong ranking function:
create table #T (ID int)
insert into #T (ID)
select 1 union all
select 2 union all
select 3
select ID,COUNT(*) OVER (PARTITION BY 1) as RowCnt from #T
drop table #T
Results:
ID RowCnt
1 3
2 3
3 3
Partitioning by a constant makes it count over the whole resultset.
Using CROSS JOIN:
SELECT a.*, b.numRows
FROM YOUR_TABLE a
CROSS JOIN (SELECT COUNT(*) AS numRows
FROM YOUR_TABLE) b
Look at the Ranking functions of SQL Server.
SELECT ROW_NUMBER() OVER (ORDER BY a) AS 'RowNumber', a, b, c
FROM table;
You could do it like this:
SELECT x.total, a, b, c
FROM
table
JOIN (SELECT total = COUNT(*) FROM table) AS x ON 1=1
which will return the total number of records in the first column, followed by fields a,b & c