make many count () in one query - sql

I have data set of call customer, I want to make count () to know:
Total number of calls for each customer
Total duration of call for each customer
Total of locations the customer he where in
This my data:
Phone no. - Duration In minutes - Location
1111 3 88
2222 4 33
3333 4 4
1111 7 55
3333 9 4
3333 7 3
the result of query:
phone no- Total number of records -Total duration of calls- Total of location
1111 2 10 2
2222 1 4 1
3333 3 20 2

This is almost similar to fthiella answer. Try like this
select PhoneNo,
count(*) as TotalNumberOfRecords,
sum(DurationInMinutes) as TotalDurationOfCalls,
count(distinct location) as TotalOfLocations from yourtablename
group by PhoneNo

You can use a GROUP BY query with basic aggregated functions, like COUNT(), SUM() and COUNT(DISTINCT) like this:
select phone_no, count(*), sum(duration), count(distinct location)
from tablename
group by phone_no

answer for your question is
select Phone no,count(Duration In minutes),sum(Duration In minutes),count(distinct Location) from Tablename group by Phone no order by Phone no;

I have made temporary table for testing and it gives same output as you mention. look following query :
declare #TEMP table (phone_no int, duration int, location int)
insert into #temp values(1111,3,88),(2222,4,33),(3333,4,4),(1111,7,55),(3333,9,4),(3333,7,3)
select phone_no, count(*), sum(duration), count(distinct location)
from #TEMP
group by phone_no
you just can consider this query :
select phone_no, count(*), sum(duration), count(distinct location)
from #TEMP
group by phone_no

Related

SQL: Adding new column to show count of ID by date

I am hoping someone can help me with my query.
I have a table with the columns, 'Date', 'ID_Num and 'Name'. What I want to do is add a column at the end to show the total amount of times each ID_Num is within the data but based on the date. So although 'ID_Num' 1001 shows 4 times in total, it is twice on the 20/04/2018 and once on both the 21/04/2018 and 22/04/2018.
EDIT: I should have stipulated that I will be pulling several other columns with information, which I cant use a group by on everything.
Date ID_Num Name Count
20/04/2018 1001 John 2
20/04/2018 1001 John 2
20/04/2018 1002 Paul 2
20/04/2018 1002 Paul 2
20/04/2018 1003 David 2
20/04/2018 1003 David 2
20/04/2018 1004 Stephen 1
21/04/2018 1001 John 1
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1002 Paul 3
21/04/2018 1004 Stephen 1
22/04/2018 1001 John 1
22/04/2018 1002 Paul 1
22/04/2018 1003 David 1
22/04/2018 1004 Stephen 1
Thanks
Unless I'm missing something here, a simple group by and count should do it:
SELECT Date, ID_Num, Name, Count(*)
FROM TableName
GROUP BY Date, ID_Num, Name
(That is, assuming there can only be one Name for each ID_Num)
Update
Assuming your rdbms supports it, you can use count with an over clause:
SELECT Date, ID_Num, Name, Count(*) OVER(PARTITION BY Date, Id_Num)
FROM TableName
If not, you can use a sub query:
SELECT Date,
ID_Num,
Name,
(SELECT Count(*)
FROM TableName As t1
WHERE t1.Date = t0.Date
AND t1.ID_NUM = t0.ID_NUM)
FROM TableName As t0
Try this:
SELECT
Date,
Id_num,
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num
If you want name as well:
SELECT
Date,
Id_num,
Name
count(*) count
FROM
tabel_name
GROUP BY
Date,
Id_num,
Name
You can use a normal select query and then add a sub query to do a group and show the total. Simple example below
SELECT Date, ID_Num, Name,
(SELECT Count(ID_Num) FROM TableName AS CHILD WHERE CHILD.Id_Num = Parent.Id_Num) AS Total
FROM TableName AS Parent

Reconciliation Automation Query

I have one database and time to time i change some part of query as per requirement.
i want to keep record of results of both before and after result of these queries in one table and want to show queries which generate difference.
For Example,
Consider following table
emp_id country salary
---------------------
1 usa 1000
2 uk 2500
3 uk 1200
4 usa 3500
5 usa 4000
6 uk 1100
Now, my before query is :
Before Query:
select count(emp_id) as count,country from table where salary>2000 group by country;
Before Result:
count country
2 usa
1 uk
After Query:
select count(emp_id) as count,country from table where salary<2000 group by country;
After Query Result:
count country
2 uk
1 usa
My Final Result or Table I want is:
column 1 | column 2 | column 3 | column 4 |
2 usa 2 uk
1 uk 1 usa
...... but if query results are same than it shouldn't show in this table.
Thanks in advance.
I believe that you can use the same approach as here.
select t1.*, t2.* -- if you need specific columns without rn than you have to list them here
from
(
select t.*, row_number() over (order by count) rn
from
(
-- query #1
select count(emp_id) as count,country from table where salary>2000 group by country;
) t
) t1
full join
(
select t.*, row_number() over (order by count) rn
from
(
-- query #2
select count(emp_id) as count,country from table where salary<2000 group by country;
) t
) t2 on t1.rn = t2.rn

countif type function in SQL where total count could be retrieved in other column

I have 36 columns in a table but one of the columns have data multiple times like below
ID Name Ref
abcd john doe 123
1234 martina 100
123x brittany 123
ab12 joe 101
and i want results like
ID Name Ref cnt
abcd john doe 123 2
1234 martina 100 1
123x brittany 123 2
ab12 joe 101 1
as 123 has appeared twice i want it to show 2 in cnt column and so on
select ID, Name, Ref, (select count(ID) from [table] where Ref = A.Ref)
from [table] A
Edit:
As mentioned in comments below, this approach may not be the most efficient in all cases, but should be sufficient on reasonably small tables.
In my testing:
a table of 5,460 records and 976 distinct 'Ref' values returned in less than 1 second.
a table of 600,831 records and 8,335 distinct 'Ref' values returned in 6 seconds.
a table of 845,218 records and 15,147 distinct 'Ref' values returned in 13 seconds.
You should provide SQL brand to know capabilities:
1) If your DB supports window functions:
Select
*,
count(*) over ( partition by ref ) as cnt
from your_table
2) If not:
Select
T.*, G.cnt
from
( select * from your_table ) T inner join
( select count(*) as cnt from your_table group by ref ) G
on T.ref = G.ref
You can use COUNT with OVERin following:
QUERY
select ID,
Name,
ref,
count(ref) over (partition by ref) cnt
from #t t
SAMPLE DATA
create table #t
(
ID NVARCHAR(400),
Name NVARCHAR(400),
Ref INT
)
insert into #t values
('abcd','john doe', 123),
('1234','martina', 100),
('123x','brittany', 123),
('ab12','joe', 101)

SQL server group by show which rows

I have a table called phonecalls which stores records of phone calls history from a company looks like this
ID Number Duration Cost
-------------------------------------
1 123456 13 1
2 222222 39 1
3 333333 69 2
4 222222 36 1
What I want to do is get sum of duration and cost for each number.
SELECT
Number,
SUM(Duration) as [Total_Duration],
SUM(Cost) as [Total_Cost]
FROM
phonecalls
GROUP BY
Number;
Now the catch is I also need which id did i included in each group by for auditing purpose so that others will know which rows are processed. So my question is how to you include ids when you do a group by?
Almighty Stackoverflow please help me.
Thanks in advance.
--EDIT:
Is it possible to get all ids with same number in one cell? something like
ID Number Total_Duration Total_Cost
---------------------------------------------------
1 123456 13 1
2,4 222222 75 2
3 333333 69 2
Hope im not asking for too much.
You're looking for the SUM OVER() function:
SQL Fiddle
SELECT
ID,
Number,
Total_Duration = SUM(Duration) OVER(PARTITION BY Number),
Total_Cost = SUM(Cost) OVER(PARTITION BY Number)
FROM phonecalls
If you want to concatenate the IDs, you can use FOR XML PATH(''):
SQL Fiddle
SELECT
ID = STUFF((
SELECT ',' + CONVERT(VARCHAR(10), ID)
FROM phonecalls
WHERE Number = p.Number
FOR XML PATH('')
), 1, 1, ''),
Number,
Total_Duration = SUM(Duration),
Total_Cost = SUM(Cost)
FROM phonecalls p
GROUP BY Number

How to select items according to their sums in SQL?

I've got the following table:
ID Name Sales
1 Kalle 1
2 Kalle -1
3 Simon 10
4 Simon 20
5 Anna 11
6 Anna 0
7 Tina 0
I want to write a SQL query that only returns the rows that
represents a salesperson with sum of sales > 0.
ID Name Sales
3 Simon 10
4 Simon 20
5 Anna 11
6 Anna 0
Is this possible?
You can easily get names of the people with the sum of sales that are greater than 0 by using the a HAVING clause:
select name
from yourtable
group by name
having sum(sales) > 0;
This query will return both Simon and Anna, then if you want to return all of the details for each of these names you can use the above in a WHERE clause to get the final result:
select id, name, sales
from yourtable
where name in (select name
from yourtable
group by name
having sum(sales) > 0);
See SQL Fiddle with Demo.
You can make it like this, I think the join will be more effective than the where name in() clause.
SELECT Sales.name, Sales.sales
FROM Sales
JOIN (SELECT name FROM Sales GROUP BY Sales.name HAVING SUM(sales) > 0) AS Sales2 ON Sales2.name = Sales.name
This will work on some databases, like oracle, mssql, db2
SELECT ID, Name, Sales
FROM
(
SELECT ID, Name, Sales, sum(sales) over (partition by name) sum1
FROM <table>
) a
WHERE sum1 > 0