Count + IIF - Access query - sql

Employees of the company are divided into categories A, B and C regardless of the division they work in (Finance, HR, Sales...)
How can I write a query (Access 2010) in order to retrieve the number of employees for each category and each division?
The final output will be an excel sheet where the company divisions will be in column A, Category A in column B, category B in column and category C in column D.
I thought an IIF() nested in a COUNT() would do the job but it actually counts the total number of employees instead of giving the breakdown by category.
Any idea?
SELECT
tblAssssDB.[Division:],
COUNT( IIF( [Category] = "A", 1, 0 ) ) AS Count_A,
COUNT( IIF( [Category] = "B", 1, 0 ) ) AS Count_B,
COUNT( IIF( [ET Outcome] = "C", 1, 0 ) ) AS Count_C
FROM
tblAssssDB
GROUP BY
tblAssssDB.[Division:];
My aim is to code a single sql statement and avoid writing sub-queries in order to calculate the values for each division.

Count counts every non-Null value ... so you're counting 1 for each row regardless of the [Category] value.
If you want to stick with Count ...
Count(IIf([Category]="A",1,Null))
Otherwise switch to Sum ...
Sum(IIf([Category]="A",1,0))

Use GROUP BY instead of IIF. Try this:
SELECT [Division:], [Category], Count([Category]) AS Category_Count
FROM tblAssssDB
GROUP BY [Division:], [Category];

Try this Count:
Count(IIf([Field1]="N",1))+Count(IIf([Field2]="N",1)) ...
I grouped my qry and place Expression under this Count field I created. It worked for me

Select count(iif(fieldname='a',1,null)) as asde
from [table name]
where .....

Related

Including count combinations with null value in SQL

I have one dataset, and am trying to list all of the combinations of said dataset. However, I am unable to figure out how to include the combinations that are null. For example, Longitudinal? can be no and cohort can be 11-20, however for Region 1, there were no patients of that age in that region. How can I show a 0 for the count?
Here is the code:
SELECT "s_safe_005prod"."ig_eligi_group1"."site_name" AS "Site Name",
"s_safe_005prod"."ig_eligi_group1"."il_eligi_ellong" AS "Longitudinal?",
"s_safe_005prod"."ig_eligi_group1"."il_eligi_elcohort" AS "Cohort",
count(*) AS "count"
FROM "s_safe_005prod"."ig_eligi_group1"
GROUP BY "s_safe_005prod"."ig_eligi_group1"."site_name",
"s_safe_005prod"."ig_eligi_group1"."il_eligi_ellong",
"s_safe_005prod"."ig_eligi_group1"."il_eligi_elcohort"
ORDER BY "s_safe_005prod"."ig_eligi_group1"."site_name",
"s_safe_005prod"."ig_eligi_group1"."il_eligi_ellong" ASC,
"s_safe_005prod"."ig_eligi_group1"."il_eligi_elcohort" ASC
Create a cross join across the unique values from each of the three grouping fields to create a set of all possible combinations. Then left join that to the counts you have originally and coalesce null values to zero.
WITH groups AS
(
SELECT a.site_name, b.longitudinal, c.cohort
FROM (SELECT DISTINCT site_name FROM s_safe_005prod.ig_eligi_group1) a,
(SELECT DISTINCT il_eligi_ellong AS longitudinal FROM s_safe_005prod.ig_eligi_group1) b,
(SELECT DISTINCT il_eligi_elcohort AS cohort FROM s_safe_005prod.ig_eligi_group1) c
),
dat AS
(
SELECT site_name,
il_eligi_ellong AS longitudinal,
il_eligi_elcohort AS cohort,
count(*) AS "count"
FROM s_safe_005prod.ig_eligi_group1
GROUP BY site_name,
il_eligi_ellong,
il_eligi_elcohort
)
SELECT groups.site_name,
groups.longitudinal,
groups.cohort,
COALESCE(dat.[count],0) AS "count"
FROM groups
LEFT JOIN dat ON groups.site_name = dat.site_name
AND groups.longitudinal = dat.longitudinal
AND groups.cohort = dat.cohort;

How can I find out the relationship between two columns in database?

I have a view defined in SQL Server database and it has two columns A and B, both of which have the type of INT. I want to find out the relationship between these two, 1 to 1 or 1 to many or many to many. Is there a SQL statement I can use to find out?
For the relationship, it means for a given value of A, how many values of B maps to this value. If there is only one value, then it is 1 to 1 mapping.
You could use CTEs to generate COUNTs of how many distinct A values were associated with each B value and vice versa, then take the MAX of those values to determine if the relationship is 1 or many on each side. For example:
WITH CTEA AS (
SELECT COUNT(DISTINCT B) ac
FROM t
GROUP BY A
),
CTEB AS (
SELECT COUNT(DISTINCT A) bc
FROM t
GROUP BY B
)
SELECT CONCAT(
CASE WHEN MAX(bc) = 1 THEN '1' ELSE 'many' END,
' to ',
CASE WHEN MAX(ac) = 1 THEN '1' ELSE 'many' END
) AS [A to B]
FROM CTEA
CROSS JOIN CTEB
Note that any time a relationship is listed as 1, it may actually be many but just not showing that because of limited data in the table.
Demo on dbfiddle
Assuming you have no NULL values:
select (case when count(*) = count(distinct a) and
count(*) = count(distinct b)
then '1-1'
when count(*) = count(distinct a) or
count(*) = count(distinct b)
then '1-many'
else 'many-many'
end)
from t;
Note: This does not distinguish between 1-many for a-->b or b-->a.
You would use count and group by to get this information.
--This would give you count of values of b which map to every values of a. If there is at least one row with a count give you a value greater than 1 it means the mapping between a and b is one to many.
select a,count( distinct b)
from table
group by a
If all of the rows have the values equal to one for all of the elements in a then the mapping is one-one
A caveat , null in b would be ignored in count expressions. ie because null and another null is not equivalent

Access Query subtract 2 different column from different row in same table with same ID

I have a table deposit which have column Refund_amt ,Deposit_amt having different Rows with same GR_no . here my question is ,I want to subtract deposit_amt column from Refund_amt
I tried various alternative in query but didn't succeed
My query :
SELECT d.Gr_no
, d.Rec_No
, d.Deposite_Amt
, d.penalty_Amt
, d.Refund_Amt - Refund
, s.Name
, s.cur_std
, cur_div
From
( select d.Refund_Amt refund
from deposite d
, std_gr s
where d.Gr_no = s.Gr_no )
Result would look like this in final total column :
Thank you
You are looking for an aggregation per std_gr: the sum of the deposites minus the sum of the refunds. One way is to do this aggregation in a subquery and join this subquery to your table.
select
d.*, sums.final_total
from deposite d
join
(
select std_gr, nz(sum(deposite_amt),0) - nz(sum(refund_amt),0) as final_total
from deposite
group by std_gr
) as sums on sums.std_gr = d.std_gr
order by d.rec_no;

Counting data with SQL

I have a table like the first table below (sorry if it doesn't show up correctly, I'm new to StackOverflow and haven't quite gotten the hang of how to show tables in the question). I've already received help do a count of IDs that are not duplicated (I don't mean a distinct count. A distinct count would return a result of 7 (a, b, c, d, e, f, g). I wanted it to return a count of 4 (a, c, d, f). These are the IDs that do not have multiple type codes). Now I need to take it a step further to show the count of how many times within a type code has a there is an ID with only that single type code. For example, we want to see a result like the second table below. There are 2 instances of IDs that have a single type code of 444 (c, f), there is one instance of an ID that has a single type code of 111 (a), and 222 (d).
For reference, the query that got me the count of IDs that have only one type code is
select count(*) from
(select id from
mytable
group by id
having count(*) =1) t
ID|type code
a|111
b|222
b|333
c|444
d|222
e|111
e|333
e|555
f|444
g|333
g|444
Type Code|Count
111|1
222|1
444|2
maybe this is what you're asking for?
SELECT [type code],
COUNT(*) [count]
FROM mytable
WHERE [ID] IN ( SELECT [ID]
FROM mytable
GROUP BY [ID]
HAVING COUNT([type code]) = 1)
GROUP BY [type code]
You can solve this using a nested aggregation:
SELECT type_code, COUNT(*)
FROM
( -- as this looks for a single row you can simply add the type code
SELECT ID, MIN(type_code) as type_code
FROM mytable
GROUP BY ID
HAVING COUNT(*) = 1
) AS dt
GROUP BY type_code

Sum the Count Visits - Sql

I came across a scenario and I am confused on how I can get it to work.
How can I SUM two different groups from the COUNT result?
Select Count(VisitID), Types
From Customers
Group by Types;
Result gets to be like:
Type VisitID
A 10
B 20
C 1
I want the result to be as follows:
Type VisitID
A+C 11
Thanks.
With a CTE for example:
WITH CustomerCounts ([Count], [Types])
AS
(
Select Count(VisitID), [Types]
from Customers
Group by [Types]
)
Select SUM([Count])
From CustomerCounts
Where [Types] in ('A', 'C')
Try this
Select only type you want then use pivot to convert row to column then sum column like this SELECT pv.[a] + pv.[c] from (..........)