How to count the number of rows with specific data in mssql - sql-server

I have the following table:
Items:
ID Type StockExists
01 Cellphone T
02 Cellphone F
03 Apparrel T
I want to count the number of items with existing stocks, i.e., the number of rows with StockExists='T'. I was performing the query as;
Select count(StockExists)
From [Items] where StockExists='T'
but it is always returning 1. What is the right way to do it?
Edit:
Also, how to perform another such Count operation and add them together in one row, for example,
Select count(StockExists)
From [Items] where StockExists='T'` and `Select count(Type)
From [Items] where Type='Cellphone'` ?

SELECT
COUNT(*) As ExistCount
FROM
dbo.Items
WHERE
StockExists='T'
So your query should work.
Result:
EXISTCOUNT
2
Demo
Update
How to perform another such Count operation and add them together in
one row, for example, Select count(StockExists) From [Items] where
StockExists='T' and Select count(Type) From [Items] where
Type='Cellphone' ?
You can use SUM with CASE:
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE 0 END) ,
CellphoneCount = SUM(CASE WHEN Type='Cellphone' THEN 1 ELSE 0 END)
FROM
dbo.Items
Result:
EXISTCOUNT CELLPHONECOUNT
2 2
Demo

Select Sum(Case when field = 'this' then 1 else 0 end) as Total
from YourTable

When using CASE WHEN better to use NULL than 0 in ELSE case like below
SELECT
ExistCount = SUM(CASE WHEN StockExists='T' THEN 1 ELSE NULL END) ,
TotalCount = COUNT(ID)
FROM
dbo.Items

Related

Retrieve CDC net changes without primary key but with unique field

I was wondering if it is possible to retrieve the net changes similar to cdc.fn_cdc_get_net_changes_<capture_instance>(from_lsn , to_lsn, 'all with mask') of tables that don't have a primary key but do have a constraint that ensures that one (or more) column(s) is unique.
It took me a while but I think I have a solution that works, let me know if there's a better solution or if you see a bug in mine.
Let's assume a capture instance named capture_instance of a table with unique column ID and non-unique columns field1, field2 and field3 and variables #from_lsn and #to_lsn.
WITH
cdc_all AS (
-- Retrieve the change table with all changes
SELECT *
FROM cdc.fn_cdc_get_all_changes_capture_instance(#from_lsn, #to_lsn, 'all')
),
f AS (
SELECT cdc_all.*, ops.[delete], ops.[insert], ops.[update], ops.[net_op]
FROM cdc_all
INNER JOIN (
-- Retrieve three flags for insert, update and delete and the net operation
-- also filter insert + delete pairs because it results in no change
SELECT *
FROM (
SELECT ID
, MAX(CASE WHEN __$operation = 1 THEN 1 ELSE 0 END) as [delete]
, MAX(CASE WHEN __$operation = 2 THEN 1 ELSE 0 END) as [insert]
, MAX(CASE WHEN __$operation = 4 THEN 1 ELSE 0 END) as [update]
, MIN(__$operation) [net_op]
FROM cdc_all
GROUP BY ID
) ops
WHERE NOT (ops.[delete] = 1 AND ops.[insert] = 1)
) ops ON cdc_all.ID = ops.ID
)
SELECT net.[max_lsn], f.[net_op] __$operation
, (CASE WHEN net.__$update_mask != 0x0 THEN net.__$update_mask ELSE NULL END) __$update_mask
, f.[ID], [field1], [field2], [field3]
FROM f
INNER JOIN (
-- bitwise OR the __$update_mask of the updates
-- also retrieve the last lsn of each row which should be used as the __$start_lsn of the result set
SELECT ID
, CAST(SUM(DISTINCT CAST((CASE WHEN f.[__$operation] = 4 AND f.[insert] != 1 THEN f.[__$update_mask] ELSE 0 END) as int)) as varbinary(2)) [__$update_mask]
, MAX(__$start_lsn) [max_lsn]
FROM f
GROUP BY ID
) net ON f.ID = net.ID AND f.__$start_lsn = net.[max_lsn]
To match the behavior of cdc.fn_cdc_get_net_changes_ exactly the size of the varbinary at the end should be as small as possible for all fields to fit, but a larger value wouldn't break the functionality.

TSQL count rows for group by

I need the count of rows after the group by.
SELECT COUNT(CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
Results:
Row 1 = 1
Row 2 = 15
Row 3 = 5
I also tried using DISTINCT
SELECT COUNT(DISTINCT CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
Results:
Row 1 = 1
Row 2 = 1
Row 3 = 1
I want the results to be 3
It seems to me the GROUP BY is entirely redundant based on what you say you want. Why not just:
SELECT COUNT(distinct CheckNumber)
FROM myTable
WHERE Status = 'Good'
If I understand correctly you could do this:
SELECT COUNT(*) FROM
(
SELECT COUNT(CheckNumber)
FROM myTable
WHERE Status = 'Good'
GROUP BY CheckNumber
) as myData
This should give you your total of 3 as requested.

Rows to Column conversion Sql query SQL SERVER

I have a table name #Table1(See the attachment) I want following out put (See the attachment)
#Raging Bull's answer is correct. Here is version using PIVOT
SELECT FormatType, [True], [False], [Blank], [True] + [False] + [Blank] AS Total
FROM
(
SELECT FormatType, Result
FROM Table1
) AS SourceTable
PIVOT
(
COUNT(Result)
FOR Result IN ([True], [False], [Blank])
) AS PivotTable
It produces the exact same result.
See result in SQL Fiddle
Try this:
SELECT FormatType,
ISNULL(COUNT(CASE WHEN Result='True' THEN '1' END),0) AS [True],
ISNULL(COUNT(CASE WHEN Result='False' THEN '1' END),0) AS [False],
ISNULL(COUNT(CASE WHEN Result='Blank' THEN '1' END),0) AS [Blank],
ISNULL(COUNT(1),0) AS [Total]
FROM Table1
GROUP BY FormatType
ORDER BY FormatType DESC
Explanation:
This query will select the FormatType along the count of each cases and the total. ISNULL is used for replacing NULL values with 0 (in case of FALSE in ASP).
Result:
FORMATTYPE TRUE FALSE BLANK TOTAL
PSP 1 2 1 4
ASP 1 0 2 3
See result in SQL Fiddle.

If any clause when grouping

Doing a Sum() on a column adds up the values in that column based on group by. But lets say I want to sum these values only if all the values are not null or not 0, then I need a clause which checks if any of the values is 0 before it does the sum. How can I implement such a clause?
I'm using sql server 2005.
Thanks,
Barry
Let's supose your table schema is:
myTable( id, colA, value)
Then, one approach is:
Select colA, sum(value)
from myTable
group by colA
having count( id ) = count( nullif( value, 0 ))
Notice that nullif is a MSSQL server function. YOu should adapt code to your rdbms brand.
Explanation:
count aggregate function only count not null values. Here a counting null values test.
You say that 0+2+3=0 for this case. Assuming that NULL+2+3 should also be zero:
SELECT GroupField,
SUM(Value) * MIN(CASE WHEN COALESCE(Value, 0) = 0 THEN 0 ELSE 1 END)
FROM SumNonZero
GROUP BY GroupField
The above statement gives this result
GroupField (No column name)
case1 5
case2 0
case3 0
with this test data
CREATE TABLE SumNonZero (
GroupField CHAR(5) NOT NULL,
Value INT
)
INSERT INTO SumNonZero(GroupField, Value)
SELECT 'case1', 2
UNION ALL SELECT 'case1', 3
UNION ALL SELECT 'case2', 0
UNION ALL SELECT 'case2', 2
UNION ALL SELECT 'case2', 3
UNION ALL SELECT 'case3', NULL
UNION ALL SELECT 'case3', 3
UNION ALL SELECT 'case3', 4
It makes no sense to eliminate 0 from a SUM because it wont impact the sum.
But you may want to SUM based on another field:
select FIELD, sum(
case when(OTHER_FIELD>0) then FIELD
else 0
end)
from TABLE
group by TABLE

SQL Server result column in WHERE clause

SELECT
MyColumn = 'something'
FROM table
WHERE MyColumn == 'something'
Possible to use MyColumn in WHERE clause?
EDIT:
Here's full query:
select TOP 10
PremiumYTDCurrent=Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END),
PremiumYTDPrevious=Sum(CASE WHEN
AASI.Inv_Acctcur>='201001'
and AASI.Inv_Acctcur<='201002'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END),
R.STAFF, L.Description, L.LINE_OF_BUSINESS
from AAS_Invoice AASI,Invoice I,Revenue_Tracking R, Policy P, Line_Of_Business L
where I.Invoice_No=convert(Char,Convert(int,AASI.Inv_Entry_Num))
and I.Invoice=R.Invoice
and I.POLICY=P.POLICY
and L.LINE_OF_BUSINESS=P.LINE_OF_BUSINESS
and R.Organization IN (SELECT ST.ORGANIZATION FROM Staff ST WHERE ST.STAFF=14407)
and R.Staff=14407
and R.Activity_type='Broker'
and R.[Percent]>0
and PremiumYTDCurrent != 0
group by R.STAFF, L.Description, L.LINE_OF_BUSINESS
order by PremiumYTDCurrent DESC, PremiumYTDPrevious DESC, average_policy DESC
You can not use the column in the where clause. Use the expression instead.
and Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END) <> 0
Edit 1
Did not notice the SUM clause.
Try add it as a HAVING clause instead after order by.
having Sum(CASE WHEN
AASI.Inv_Acctcur>='201101'
and AASI.Inv_Acctcur<='201102'
THEN (AASI.Inv_Premium)*R.[Percent]
ELSE 0 END) != 0
You could wrap the SQL up in a nested statement, a horrendously simple example being, e.g.:
SELECT MyMadeUpColumnName, col2, AnotherMadeUpColumn FROM (
SELECT SUM(sillycolumn) AS 'MyMadeUpColumnName', col2 FROM table GROUP BY col2
) AS t
WHERE t.AnotherMadeUpColumn <> 0
Any column names that you (re)define in the derived table become the actual column names for the parent select.

Resources