Count total number of records based on answers - sql

i have a result which displays two answers and i want to result the total number of counts by each record. With my query i display two answers (like and dislike). i want to count the total number of like and also the total number of dislike
SELECT (CASE WHEN log_time <= rdate_up THEN 'like' ELSE 'dislike' end )as answer
FROM dbo.users

Considering the algorithm you gave us to validate if value is a like or dislike is
log_time <= rdate_up
Then you could use union and count to separate them.
select count(*) as count_of_like
from dbo.users
where log_time <= rdate_up
union
select count(*) as count_of_dislike
from dbo.users
where log.time > rdate_up;

You can do this another way using CASE. This will be faster because it only hits the base table once.
select sum(case when log_time <= rdate_up then 1 end) as LikeCount
, SUM(case when log.time > rdate_up then 1 end) as DislikeCount
from dbo.users

Related

How to sum count on specific columns in sql

I want to calculate specific sum of counts
select is_known_bot, count(*)
FROM "public"."bus_request"
where app_name = 'xxxxxx' and event_type <> 'browser_js'
and is_known_bot <>''
and date <= GETDATE() and date>= GETDATE()-14
group by is_known_bot
order by is_known_bot asc
I am getting the below table:
is_known_bot count
good 2
bad 3
Human 7
in the end, i want to get the below table:
is_known_bot count
bot 5
Human 7
You can use CASE instead the column is_know_bot
Case when is_know_bot = 'Human' then is_know_bot else 'Bot' end

How can one count total records AND separately count records where two fields are equal

Let say I have the following table called VISITS:
I need to count the total records for each location, and then have a separate count of those records where Date1 and Date2 values are equal. The final results should look like this:
I can get a count of total using:
select Location, Count(*) as 'Total Visits' from Visits Group by Location
And I can get a count of visits that match by doing
select Location, Count(*) as 'Total Matched' From Visits
where Date1 = Date2 group by Location
But I don't know how to do both counts with a single query.
Use conditional aggregation:
select v.Location, Count(*),
sum(case when v.date1 = v.date2 then 1 else 0 end) as same_day
from Visits v
group by v.location;
Note that your queries are missing the group by clause.
a simple way could be
select Location, Count(*), sum(case when Date1 = Date2 then 1 else 0 end)
from Visits
group by location

SQL: how to aggregate value with conditions (CASE WHEN???)

My data has 3 variables, User ID, Transaction Amount, and Transaction Date,
I want to aggregate 2 day transaction amount for each user ID, but with conditions.
The condition is, for example, I want to aggregate 8/31 and 8/30 transaction amount for an ID 12345, if the transaction amount is 0 on 8/31 for this ID, which means this ID does not have any transactions on 8/31, then just ignore this user ID, I'm not going to aggregate amount for this user ID.
If another ID 23456 has transactions on 8/31 and does not have transaction on 8/30, then I will aggregate the transactions on 8/31 for this ID.
If one ID 34567 has transactions on both 8/30 and 8/31, then I will have aggregate the transactions for both 8/30 and 8/31.
How can I do this? I've been struggling for the whole afternoon. Thanks in advance for any suggestions and idea!
Based on your question should be
select user_id, sum(a.transaction_amount + b.transaction_amount).
from my_table as a
inner join my_table as b on date_add(b.transaction_date, interval 1 day) = a.transaction_date
where date(a.transaction_date) = STR_TO_DATE('31,8,2016','%d,%m,%Y')
and a.transaction_amount > 0
group by user_id
SELECT User_ID, SUM(Transaction_Amount)
FROM yourTable
WHERE DATE(Transaction_Date) = '2016-08-30'
OR (DATE(Transaction_Date) = '2016-08-31' AND Transaction_Amount > 0)
GROUP BY User_ID
Just use conditional aggregation:
select userid,
sum(case when date = '2016-08-30' then amount else 0 end) as amt_20160830,
sum(case when date = '2016-08-31' then amount else 0 end) as amt_20160831
from t
group by userid
having sum(case when date = '2016-08-31' then amount else 0 end) > 0;
Exactly what the code looks like might vary by databases, but this is fairly standard SQL.
Seems like you want to return only users which had a transaction on Aug. 31.:
select userid,
sum(trans_amount)
from t
where trans_date between date '2016-08-30' and date '2016-08-31'
group by userid
having max(trans_date) = date '2016-08-31'

select query output not as expected

i need one single query which will give result like the one i give below
createddate recordcount acceptdate submitdate createddate
27-MAR-16 24 36 11
28-MAR-16 79 207 58
for reference i am providing some queries which i want to merge into one single query
select trim(date_created) createddate,count(*) recordcount
from man
where status IN ('CREATED')and date_created>sysdate-15
group by trim(date_created) ORDER BY TO_DATE(createddate,'DD/MM/YYYY');
this query will result like the following.
createddate recordcount
27-MAR-16 11
28-MAR-16 58
the second query
select trim(DATE_SUB) submitdate,count(*) recordcount
from man
where status IN ('SUBMITTED')and DATE_SUB>sysdate-15
group by trim(date_sub) ORDER BY TO_DATE(submitdate,'DD/MM/YYYY');
result of this query is like
submitdate recordcount
27-MAR-16 36
28-MAR-16 207
and the third query is like -
select trim(DATE_PUB) acceptdate,count(*) recordcount
from man
where status IN ('ACCEPTED')and DATE_PUB>sysdate-15
group by trim(DATE_PUB) ORDER BY TO_DATE(acceptdate,'DD/MM/YYYY');
acceptdate recordcount
27-MAR-16 24
28-MAR-16 79
how can i merger these three query so that i can get count for all in single query?which will give me result like
createddate recordcount acceptdate submitdate createddate
27-MAR-16 24 36 11
28-MAR-16 79 207 58
Your first query where clause has date but second query where clause has DATE_P.
Try like this
SELECT Trim(date) createddate,
COUNT(*) recordcount,
SUM(case when status = 'A' then 1 else 0 end) as a,
SUM(case when status = 'S' then 1 else 0 end) as s,
SUM(case when status = 'C' then 1 else 0 end) as c,
SUM(case when status = 'R' then 1 else 0 end) as r
FROM man
WHERE status IN ('A','S','C','R')and date >sysdate-15
GROUP BY trim(date) ORDER BY createddate;
You seem to want to get counts for each status type, for each day. The first step is generate all the dates you're interested in, which you can do with:
select trunc(sysdate) + 1 - level as dt
from dual
connect by level <= 15;
You can then (outer) join to your actual table where any of the three date columns match a generated date, and expand your case conditions to check which one you're looking at:
with t as (
select trunc(sysdate) + 1 - level as dt
from dual
connect by level <= 15
)
select t.dt,
count(*) as recordcount,
count(case when status = 'ACCEPTED' and trunc(m.date_pub) = t.dt
then 1 end) as acceptdate,
count(case when status = 'SUBMITTED' and trunc(m.date_sub) = t.dt
then 1 end) as submitdate,
count(case when status = 'CREATED' and trunc(m.date_created) = t.dt
then 1 end) as createddate
from t
left join man m
on (m.date_pub >= t.dt and m.date_pub < t.dt + 1)
or (m.date_sub >= t.dt and m.date_sub < t.dt + 1)
or (m.date_created >= t.dt and m.date_created < t.dt + 1)
group by t.dt
order by t.dt;
I've used range checks for the join conditions - it isn't clear if all your date columns are set at midnight, but it's safer to assume they might have other times and you cant everything from the matching day.
Each of the three count results is now only of those rows which match the status and where the specific date column matches, which I think is what you want. I've used trunc() here instead of a range comparison, as it doesn't have the potential performance penalty you can see in the where clause (from it potentially stopping an index being used).
This may throw out your recordcount though, depending on your actual data, as that will include rows that now might not match any of the case conditions. You can repeat the case conditions, or use an inline view to calculate the total of the three individual counts, depending on what you want it to include and what will be the easiest for you to maintain. If those are the only three statuses in your table then it may be OK with count(*) but check it gets the value you expect.

change rows to columns and count

how to calculate count based on rows?
SOURCE TABLE
each employee can take 2 days off
Employee-----First_Day_Off-----Second_Day_Off
1------------10/21/2009--------12/6/2009
2------------09/3/2009--------12/6/2009
3------------09/3/2009--------NULL
4
5
.
.
.
Now i need a table that shows the dates and number of people taking off on that day
Date---------First_Day_Off-------Second_Day_Off
10/21/2009---1-------------------0
12/06/2009---1--------------------1
09/3/2009----2--------------------0
Any ideas?
Oracle 9i+, using Subquery Factoring (WITH):
WITH sample AS (
SELECT a.employee,
a.first_day_off AS day_off,
1 AS day_number
FROM YOUR_TABLE a
WHERE a.first_day_off IS NOT NULL
UNION ALL
SELECT b.employee,
b.second_day_off,
2 AS day_number
FROM YOUR_TABLE b
WHERE b.second_day_off IS NOT NULL)
SELECT s.day_off AS date,
SUM(CASE WHEN s.day_number = 1 THEN 1 ELSE 0 END) AS first_day_off,
SUM(CASE WHEN s.day_number = 2 THEN 1 ELSE 0 END) AS second_day_off
FROM sample s
GROUP BY s.day_off
Non Subquery Version
SELECT s.day_off AS date,
SUM(CASE WHEN s.day_number = 1 THEN 1 ELSE 0 END) AS first_day_off,
SUM(CASE WHEN s.day_number = 2 THEN 1 ELSE 0 END) AS second_day_off
FROM (SELECT a.employee,
a.first_day_off AS day_off,
1 AS day_number
FROM YOUR_TABLE a
WHERE a.first_day_off IS NOT NULL
UNION ALL
SELECT b.employee,
b.second_day_off,
2 AS day_number
FROM YOUR_TABLE b
WHERE b.second_day_off IS NOT NULL) s
GROUP BY s.day_off
It is a bit awkward to handle these queries, since you have days off stored in different columns. A better layout would be to have something like
EMPLOYEE_ID DAY_OFF
Then you would have multiple rows if an employee took multiple days off
EMPLOYEE_ID DAY_OFF
1 10/21/2009
1 12/6/2009
2 09/3/2009
2 12/6/2009
3 09/3/2009
...
In that case, you could find out how many days off each person took by using the following query:
SELECT EMPLOYEE_ID, COUNT(*) AS NUM_DAYS_OFF FROM DAYS_OFF_TABLE GROUP BY EMPLOYEE_ID
And the number of people who took days off on each date like this:
SELECT DAY_OFF, COUNT(*) AS NUM_PEOPLE FROM DAYS_OFF_TABLE GROUP BY DAY_OFF
But I digress...
You can try to use an SQL CASE statement to help with this:
SELECT Employee, CASE
WHEN First_Day_Off is NULL AND Second_Day_Off is NULL THEN 0
WHEN First_Day_Off is NOT NULL AND Second_Day_Off is NULL THEN 1
WHEN First_Day_Off is NULL AND Second_Day_Off is NOT NULL THEN 1
ELSE 2
END AS NUM_DAYS_OFF
FROM DAYS_OFF_TABLE
(note that you may need to change around the syntax slightly depending on your database.
Getting dates and number of people who took off on that day might be more complicated.
I don't know if this would work, but you can try it:
SELECT
Date_Off,
COUNT(*) AS Num_People
FROM
(SELECT
First_Day_Off, COUNT(*) AS Num_People FROM DAYS_OFF_TABLE WHERE First_Day_Off IS NOT NULL GROUP BY First_Day_Off
UNION
SELECT Second_Day_Off, COUNT(*) AS Num_People FROM DAYS_OFF_TABLE WHERE Second_Day_Off IS NOT NULL GROUP BY Second_Day_Off)
GROUP BY
Num_People