sql restricted count query - sql

I'm not certain how to structure a SQL query to return the number of rows where a column equals certain values.
For instance,
In table myTable, how can I return the count of all the rows where myColumn = "xyz" and where myColumn = "abc"? Is this possible with a single query?
To clarify, say there are 10 rows where myColumn = "xyx" and 7 rows where myColumn = "abc", the query would return something like:
firstCountResult: 10
secondCountResult: 7

How about?:
SELECT
COUNT(*),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn
This approach also works with other aggregate functions like MIN, MAX, AVG, SUM... You get the aggregate result per the grouped column's value versus across all rows.
--min myDate per myColumn value
SELECT
MIN(myDate),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn
--sum of myNumericCol per myColumn value
SELECT
SUM(myNumericCol),
myColumn
FROM myTable
WHERE myColumn IN ('xyz', 'abc')
GROUP BY myColumn

You want to group the count by mycolumn so you do this
select
myColumn, count(*)
from
myTable
where
myColumn in ('xyz','abc')
group by
myColumn

Related

Counting the number of NULLs in a SQL Server Column

I have two queries like so:
SELECT MyId, MyColumn FROM MyTable WHERE MyColumn IS NULL;
SELECT count(MyColumn) as MyCount FROM MyTable WHERE MyColumn IS NULL;
The results I get are:
MyId MyColumn
10 NULL
Why is the count 0 always in the second query?
The COUNT() function ignores NULL values, and so the count in your second query will always be zero. Either count something else:
SELECT COUNT(*) AS MyCount
FROM MyTable
WHERE MyColumn IS NULL;
Or else count over the entire table using a CASE expression to explicitly count NULL values:
SELECT COUNT(CASE WHEN MyColumn IS NULL THEN 1 END) AS MyCount
FROM MyTable;
Count doesn't count null.
You need to do something like this, transform null to 1 then sum them:
SELECT SUM(CASE WHEN MyColumn IS NULL THEN 1 ELSE 0 END) AS count_nulls
FROM MyTable;
You can simply use count(1) rather than column name in the count function as it ignores null value which counting.
SELECT COUNT(1) AS MyCount
FROM MyTable
WHERE MyColumn IS NULL;
As noted, COUNT(SomeValue) just counts the number of non-nulls, so you actually needed COUNT(*).
But another way is to subtract the non-nulls from the total
SELECT COUNT(*) - COUNT(MyColumn) AS MyCount
FROM MyTable;
A WHERE is probably faster though, especially if you have an index on that column.

How to change a UNION to a IN clause?

I need to get a maximum of 3 distinct records from the same table, so currently I'm doing:
SELECT 1, mycolumn FROM mytable WHERE id = #firstId
UNION ALL
SELECT 2, mycolumn FROM mytable WHERE id = #secondId
UNION ALL
SELECT 3, mycolumn FROM mytable WHERE id = #thirdId
The actual SELECT part contains over 20 columns and the FROM part contains a number of JOINs. The first column is a constant and is always fixed depending on the record. I don't know how many records might return. It could be anything from 0 to 3 records.
Is it possible to change the above query so that it uses IN like this:
SELECT ???, mycolumn FROM mytable WHERE id IN (#firstId, #secondId, #thirdId)
But how do I explicitly map each record to the fixed constant if I use IN?
You may use a CASE expression here with a single query:
SELECT
CASE id WHEN #firstId THEN 1
WHEN #secondId THEN 2
WHEN #thirdId THEN 3 END AS val,
mycolumn
FROM mytable
WHERE
id IN (#firstId, #secondId, #thirdId);
If you wish to also order by the computed column, then add ORDER BY val to the end of the above query.
You can use CASE like following.
SELECT
CASE
WHEN id= #firstId THEN 1
WHEN id=#secondId THEN 2
ELSE 3
END AS rn,
mycolumn
FROM mytable
WHERE id IN (#firstId,
#secondId,
#thirdId)
Another approach can be using DENSE_RANK if you have one record for each provided id and #firstId, #secondId & #thirdId are in ascending order.
SELECT DENSE_RANK()
OVER(
ORDER BY id) rn,
mycolumn
FROM mytable
WHERE id IN ( #firstId, #secondId, #thirdId )
I would recommend a table-valued constructor for this purpose:
select v.outputnum, my_column
from mytable t join
(values (#firstid, 1),
(#secondid, 2),
(#thirdid, 3)
) v(id, outputnum)
on t.id = v.id
order by v.outputnum;
I think this is simpler than other versions, because the list of ids is only present once in the query -- so no danger of different parts of the query getting out of sync.

SQL Server Sum of column1 of all distinct values of column2

I am trying to find the SUM of column1 of all Distinct values of column2. Is it possible?
You could try something like this:
Select SUM(ColA), ColB
from table
Group by ColB
You almost wrote the query yourself in that sentence:
SELECT Column2, SUM(Column1) FROM Table GROUP BY Column2
It's not entirely clear what you're asking...
...this adds all the values in column 1 for each distinct value in column 2 then gives a total of all values in column 1:
SELECT Column2,SUM(Column1) FROM Table GROUP BY Column2 with rollup
Note: If you want the rollup at the top of the output put distinct in it.
SELECT distinct Column2,SUM(Column1) FROM Table GROUP BY Column2 with rollup

SQL QUERY - Omit ALL duplicate results

I need to return values in a column where only the unique values are returned. I know that DISTINCT will return only unique values, however i need to completely omit any that are duplicated.
i.e.
Column 1 Column 2
----------------------
123456789 27/02/2014
123456789 25/02/2014
654789897 27/02/2014
To return only "654789897 27/02/2014" and omit the other results.
You want to use group by and having:
select column1, column2
from table t
group by column1, column2
having count(*) = 1;
EDIT: (based on comment by knkarthick24)
Depending on what the OP intends, this might also be correct:
select column1, max(column2)
from table t
group by column1
having count(*) = 1;
select column1,column2
from tbl
where column1 in(
select column1
from table
group by column1 having count(column1)=1)
Its good to have Having and GroupBy
Let me know if that works:)

SQL: Retrieve value from a column that occurred least number of times

I have a table which have a single field. and it have a values like (3,7,9,11,7,11)
Now I want a query which will pick the value that occurred least number of times and if there is a tie with minimum occurrences then use the smallest number
In this case the answer will be 3.
Something like this:
SELECT TOP 1 COUNT(*), myField
FROM myTable
GROUP BY (myField)
ORDER BY COUNT(*) ASC
ADDITIONAL: And to taking into account the tie-breaker situation:
SELECT TOP 1 COUNT(*), myField
FROM myTable
GROUP BY (myField)
ORDER BY COUNT(*) ASC, myField ASC
In MySQL and PostgreSQL:
SELECT *
FROM (
SELECT field, COUNT(*) AS cnt
FROM mytable
GROUP BY
field
) q
ORDER BY
cnt, field
LIMIT 1
Assuming you're using SQL Server: if you have ties for the least frequent number, and you want all ties returned, then you could do something like this:
DECLARE #temp table (
count int,
myField int
)
INSERT #temp
SELECT COUNT(*), myField
FROM myTable
GROUP BY (myField)
DECLARE #minCount int
SELECT #minCount = MIN(count)
FROM #temp
SELECT count, myField
FROM #temp
WHERE count = #minCount