How to SELECT Distinct Count from SELECT with Union All SELECT - tsql

I need to get a count from a query with UNION ALL, but all my attempts so far have failed and I cannot get it to work.
My Initial SELECT (Which returns 8 unique departments)
select distinct Department
from ( select Department
from EFP_EmployeeFollowupManagerCommit
union all
select Department from EFP_EmploymentUser )
a order by Department;
I have tried different variations of the following
SELECT COUNT(Department) as "DepCount"
FROM ( select Department
from EFP_EmployeeFollowupManagerCommit
union all
select Department
from EFP_EmploymentUser );
Can anyone help?
UPDATE!
I finally got it to work .. thank you to all :-)
The final query:
select count(*) from (
select distinct Department
from (
select Department
from EFP_EmployeeFollowupManagerCommit
union all
select Department
from EFP_EmploymentUser ) as ddep) as depcount;

You can try the following query, it should work:
select count(*) from (select distinct Department
from ( select Department from EFP_EmployeeFollowupManagerCommit
union all
select Department from EFP_EmploymentUser ));

You have to write like this:
select count(distinct Department)

Related

Calculate difference between the row counts of tables in two schemas in PostgreSQL

I have two table with same name in two different schemas (old and new dump). I would like to know the difference between the two integration.
I have two queries, that gives old and new count:
select count(*) as count_old from(
SELECT
distinct id
FROM
schema1.compound)q1
select count(*) as count_new from(
SELECT
distinct id
FROM
schema2.compound)q2
I would like have the following output.
table_name count_new count_new diff
compound 4740 4735 5
Any help is appreciated. Thanks in advance
with counts as (
select
(select count(distinct id) from schema1.compound) as count_old,
(select count(distinct id) from schema2.compound) as count_new
)
select
'compound' as table_name,
count_old,
count_new,
count_old - count_new as diff
from counts;
I think you could do something like this:
SELECT 'compound' AS table_name, count_old, count_new, (count_old - count_new) AS diff FROM (
SELECT(
(SELECT count(*) FROM (SELECT DISTINCT id FROM schema1.compound)) AS count_old,
(SELECT count(*) FROM (SELECT DISTINCT id FROM schema2.compound)) AS count_new
)
It was probably answered already, but it is a subquery/nested query.
You can directly compute the COUNT on distinct values if you use the DISTINCT keyword inside your aggregation function. Then you can join the queries extracting your two needed values, and use them inside your query to get the output table.
WITH cte AS (
SELECT new.cnt AS count_new,
old.cnt AS count_old
FROM (SELECT COUNT(DISTINCT id) AS cnt FROM schema1.compound) AS old
INNER JOIN (SELECT COUNT(DISTINCT id) AS cnt FROM schema2.compound) AS new
ON 1 = 1
)
SELECT 'compound' AS table_name,
count_new,
count_old,
count_new = count_old AS diff
FROM cte

How to get count(*) total from DB2 with having clause?

How do I get the sum of all return rows with group by clause in DB2?
For example:
Desc Ctr
---- ---
Bowl 30
Plate 21
Spoon 6
Sum 57
SELECT COUNT (name) as Desc, Count(*) OVER ALL
GROUP BY name
Above query return error from DB2. What is the proper SQL statement to return SUM of all rows?
Thanks,
Brandon.
Try this query,
select name, count(*) from table group by name
What is your platform of Db2?
If you want just the total count of rows, then
select count(*)
from mytable
If you want the subtotals by name plus the total, SQL didn't originally support that. You had to union the two results.
select name, count(*) as cnt
from mytable
group by name
UNION ALL
select '', count(*)
from mytable
However more modern versions have added ROLLUP (and CUBE) functionality...
select name, count(*) as cnt
from mytable
group by name with rollup
Edit
To put a value for name, you could simply use COALESCE() assuming name won't ever be null except in the total row.
select coalesce(name,'-Total-') as name, count(*) as cnt
from mytable
group by name with rollup
The more correct method is to use the GROUPING() function
either return just the flag
select name, count(*) as cnt, grouping(name) as IS_TOTAL
from mytable
group by name with rollup
or use it to set the text
select case grouping(name)
when 1 then '-Total-'
else name
end as name
, count(*) as cnt
from mytable
group by name with rollup
Inculde total
To include the total on each line, you could do something like so...
with tot as (select count(*) as cnt from mytable)
select name
, count(*) as name_cnt
, tot.cnt as total_cnt
from mytable
cross join tot
group by name
Note that this will read mytable twice, once for the total and again for the detail rows. But it's real obvious what you're doing.
Another option would be something like so
with allrows as (
select name, count(*) as cnt, grouping(name) as IS_TOTAL
from mytable
group by name with rollup
)
select dtl.name, dtl.cnt, tot.cnt
from allrows dtl
join allrows tot
on tot.is_total = 1
where
dtl.is_total = 0

SQL Server SUM() for DISTINCT records

I have a field called "Users", and I want to run SUM() on that field that returns the sum of all DISTINCT records. I thought that this would work:
SELECT SUM(DISTINCT table_name.users)
FROM table_name
But it's not selecting DISTINCT records, it's just running as if I had run SUM(table_name.users).
What would I have to do to add only the distinct records from this field?
Use count()
SELECT count(DISTINCT table_name.users)
FROM table_name
SQLFiddle demo
This code seems to indicate sum(distinct ) and sum() return different values.
with t as (
select 1 as a
union all
select '1'
union all
select '2'
union all
select '4'
)
select sum(distinct a) as DistinctSum, sum(a) as allSum, count(distinct a) as distinctCount, count(a) as allCount from t
Do you actually have non-distinct values?
select count(1), users
from table_name
group by users
having count(1) > 1
If not, the sums will be identical.
You can see for yourself that distinct works with the following example. Here I create a subquery with duplicate values, then I do a sum distinct on those values.
select DistinctSum=sum(distinct x), RegularSum=Sum(x)
from
(
select x=1
union All
select 1
union All
select 2
union All
select 2
) x
You can see that the distinct sum column returns 3 and the regular sum returns 6 in this example.
You can use a sub-query:
select sum(users)
from (select distinct users from table_name);
SUM(DISTINCTROW table_name.something)
It worked for me (innodb).
Description - "DISTINCTROW omits data based on entire duplicate records, not just duplicate fields." http://office.microsoft.com/en-001/access-help/all-distinct-distinctrow-top-predicates-HA001231351.aspx
;WITH cte
as
(
SELECT table_name.users , rn = ROW_NUMBER() OVER (PARTITION BY users ORDER BY users)
FROM table_name
)
SELECT SUM(users)
FROM cte
WHERE rn = 1
SQL Fiddle
Try here yourself
TEST
DECLARE #table_name Table (Users INT );
INSERT INTO #table_name Values (1),(1),(1),(3),(3),(5),(5);
;WITH cte
as
(
SELECT users , rn = ROW_NUMBER() OVER (PARTITION BY users ORDER BY users)
FROM #table_name
)
SELECT SUM(users) DisSum
FROM cte
WHERE rn = 1
Result
DisSum
9
If circumstances make it difficult to weave a "distinct" into the sum clause, it will usually be possible to add an extra "where" clause to the entire query - something like:
select sum(t.ColToSum)
from SomeTable t
where (select count(*) from SomeTable t1 where t1.ColToSum = t.ColToSum and t1.ID < t.ID) = 0
May be a duplicate to
Trying to sum distinct values SQL
As per Declan_K's answer:
Get the distinct list first...
SELECT SUM(SQ.COST)
FROM
(SELECT DISTINCT [Tracking #] as TRACK,[Ship Cost] as COST FROM YourTable) SQ

display unique row from two tables

I have two tables (one for quarter one, one for quarter two), each of which contains employees who have bonus in that quarter. Every employee has a unique id in the company.
I want to get all employees who has bonus in either q1 or q2. No duplicate employee is needed. Both Id, and Amount are required.
Below is my solution, I want to find out if there is a better solution.
declare #q1 table (
EmployeeID int identity(1,1) primary key not null,
amount int
)
declare #q2 table (
EmployeeID int identity(1,1) primary key not null,
amount int
)
insert into #q1
(amount)
select 1
insert into #q1
(amount)
select 2
select * from #q1
insert into #q2
(amount)
select 1
insert into #q2
(amount)
select 11
insert into #q2
(amount)
select 22
select * from #q2
My Solution:
;with both as
(
select EmployeeID
from #q1
union
select EmployeeID
from #q2
)
select a.EmployeeID, a.amount
from #q1 as a
where a.EmployeeID in (select EmployeeID from both)
union all
select b.EmployeeID, b.amount
from #q2 as b
where b.EmployeeID in (select EmployeeID from both) and b.EmployeeID NOT in (select EmployeeID from #q1)
Result:
EmployeeID, Amount
1 1
2 2
3 22
SELECT EmployeeID, Name, SUM(amount) AS TotalBonus
FROM
(SELECT EmployeeID, Name, amount
from #q1
UNION ALL
SELECT EmployeeID, Name, amount
from #q2) AS all
GROUP BY EmployeeID, Name
The subselect UNIONS both tables together. The GROUP BY gives you one row per employee and the SUM means that if someone got lucky in both qs then you get the total. I'm guessing that's the right thing for you.
try this one:
SELECT EmployeeID
FROM EmployeeList
WHERE EmployeeID IN
(SELECT EmployeeID From QuarterOne
UNION
SELECT EmployeeID From QuarterTwo)
OR by using JOIN
SELECT EmployeeID
FROM EmployeeList a INNER JOIN QuarterTwo b
ON a.EmployeeID = b.EmployeeID
INNER JOIN QuarterTwo c
ON a.EmployeeID = c.EmployeeID
This will return all EmployeeID that has record in either quarter.
Try:
SELECT DISTINCT q1.EmployeeID --- Same as q2.EmployeeID thanks to the join
, q1.EmployeeName -- Not defined in OP source.
FROM #q1 AS q1
CROSS JOIN #q2 AS q2
WHERE q1.amount IS NOT NULL
OR q2.amount IS NOT NULL

Select distinct from another select results

I want to select distinct results from another select statement results
e.g;
select distinct from(select * from table)
following is result of inner select
testing department 9998901036 GOLD
testing department 9998901036 GOLD
I want to get distinct from above select result.
From your example, you could just do
select distinct * from table
But say you had some scenario where you wanted to distinct on some other results set, you could do
select distinct column1, column2 from (select * from table) T
Note that you have to alias your inner select
select distinct *
from
(select * from table) t
Works - You just need to give your sub select a table alias.
You can also use a CTE.
;WITH t AS
(
SELECT *
FROM table
)
SELECT DISTINCT *
FROM t