How to generate a count based on Text data in SQL - sql

I have the following table:
I basically want to Pivot the contents of the Status column and generate a count of the 'Issuer/Ticker' column. For example, I want to know for Allison Shenoy, what is the number of "Issuer/Ticker" that are Past Due and that are "Due within 3 months". So, my answer should read for this analyst: Past Due: 11 and Due within 3 months: 8 based on the data above.

Use conditional aggregation:
select
assigned_analyst,
sum(case when status = 'Past Due' then 1 else 0 end) past_due,
sum(case when status = 'Due within 3 Months' then 1 else 0 end) due_3_month
from mytable
group by assigned_analyst

To get the counts of Issuer/Ticker based on each analyst and status, try this:
SELECT
[Assigned Analyst]
,[Status]
COUNT(distinct [Issuer/Ticker]) [Count of Issuer/Ticker]
FROM TableName
GROUP BY [Assigned Analyst], [Status]
Otherwise, to get the counts for Allison Shenoy only, try this:
SELECT
[Status]
COUNT(distinct [Issuer/Ticker]) [Count of Issuer/Ticker]
FROM TableName
WHERE [Assigned Analyst] = 'Allison Shenoy'
GROUP BY [Status]
Obviously, replace 'TableName' with the actual name of the table

Related

aggregate function error in case expression

I have this query
SELECT mylearning.Employee_Id,
case
when max(case when not mylearning.CourseStatusTXT = 'Completed' then 1 else 0 end) = 0 then '2018 Complete'
when max(case when mylearning.CourseStatusTXT in ('Started', 'Not Started') then 1 else 0 end) = 1 then '2018 Not Complete'
end as Completion_Status
FROM Analytics.myLearning_Completions as mylearning inner join Analytics.Workday WD on mylearning.Employee_ID = WD.Employee_ID
And I want to add a condition to the first when statement to make it like this
when max(case when not mylearning.CourseStatusTXT = 'Completed' then 1 else 0 end) = 0
and WD.Adjusted_Hire_Date like '2019% '
and mylearning.CourseTimeCompletedH < cast (WD.Adjusted_Hire_Date as date format 'YYYY/MM/DD') +7
then '2018 Complete'
but I keep getting this error
Executed as Single statement. Failed [3504 : HY000] Selected non-aggregate values must be part of the associated group.
Elapsed time = 00:00:00.069
How can I fix it?
Like a couple others mentioned, you are trying to mix grouped data with non-aggregated data in your calculation, which is why you're getting the 3504 error. You need to either include the referenced columns in your GROUP BY or include them inside an aggregate function (i.e. MAX).
I'm not 100% sure if this is what you're after, but hopefully it can help you along.
SELECT
mylearning.Employee_Id,
CASE
WHEN
MAX(CASE WHEN NOT mylearning.CourseStatusTXT = 'Completed' THEN 1 ELSE 0 END) = 0 AND
WD.Adjusted_Hire_Date like '2019% ' AND
-- Check if most recently completed course is before Hire (Date + 1 week)
MAX(mylearning.CourseTimeCompletedH) <
CAST(WD.Adjusted_Hire_Date AS DATE FORMAT 'YYYY/MM/DD') + 7
THEN '2018 Complete' -- No incomplete learnings
WHEN MAX(
CASE WHEN mylearning.CourseStatusTXT IN ('Started', 'Not Started') THEN 1 ELSE 0 END
) = 1 THEN '2018 Not Complete' -- Started / Not Started learnings exist
END AS Completion_Status
FROM Analytics.myLearning_Completions as mylearning -- Get learning info
INNER JOIN Analytics.Workday WD on mylearning.Employee_ID = WD.Employee_ID -- Employee info
GROUP BY mylearning.Employee_Id, WD.Adjusted_Hire_Date
This will give you a summary per employee, with a couple assumptions:
Assuming employee_ID value in Analytics.Workday is a unique value (one-to-one join), to use WD.Adjusted_Hire_Date in your comparisons, you just need to include it in the GROUP BY.
Assuming you have multiple courses per employee_Id, in order to use mylearning.CourseTimeCompletedH in your comparisons, you'd need to wrap that in an aggregate like MAX.
The caveat here is that the query will check if the most recently completed course per employee is before the "hire_date" expression, so I'm not sure if that's what you're after.
Give it a try and let me know.
The issue here is that you are mixing detail row by row information in the same query as group or aggregated data. Aggregated data will output a single value for all the rows unless you have a group by clause. If you have a group by clause then it will output a single value for each group. When you are grouping you can also include any values that are in the group by clause since they will be unique for the group.
if you want this data for each employee, then you could group by employee_id. Any other data would need to also be an aggregate like Max(Adjusted_Hire_Date)
Maybe this is what you want?
SELECT
mylearning.employee_id
, case
when CourseStatusTXT = 'Completed' and WD.Adjusted_Hire_Date like '2019%'
and mylearning.CourseTimeCompletedH < cast (WD.Adjusted_Hire_Date as date format 'YYYY/MM/DD') +7
then '2018 Complete'
else '2018 Not Complete'
end CompletionStatus
FROM myLearning_Completions mylearning, Workday WD
WHERE mylearning.employee_id = WD.employee_id

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

SQL - Group data with same ID and Date that has been to every Machine but has a different Name

I am trying to create a query that will group data by CT ID and Date that have all 3 MachineID's (1, 10, and 20) and at least one different Sawing Pattern Name.
This Image shows a highlighted example of the data I'm trying to get back and the code i'm currently using
I'm trying to only show data similar to the highlighted rows in the image (CT ID 501573833) and exclude the data in the rows around it where the Sawing Pattern Name is the same at all 3 MachineID's.
Your description suggests group by and having. The conditions you describe can all go in the having clause:
select ct_id, date
from t
group by ct_id, date
having sum(case when machineid = 1 then 1 else 0 end) > 0 and
sum(case when machineid = 10 then 1 else 0 end) > 0 and
sum(case when machineid = 20 then 1 else 0 end) > 0 and
min(sawing_pattern_name) <> max(sawing_pattern_name)
Seems to me that an EXISTS could be useful here.
SELECT
[CT ID],
[MachineID],
[Sawing Pattern name],
[Time],
CAST([Time] AS DATE) AS [Date]
FROM [DataCollector].[dbo].[Maxicut] t
WHERE EXISTS
(
SELECT 1
FROM [DataCollector].[dbo].[Maxicut] d
WHERE d.[CT ID] = t.[CT ID]
AND CAST(d.[Time] AS DATE) = CAST(t.[Time] AS DATE)
AND d.[MachineID] != t.[MachineID]
AND REPLACE(d.[Sawing Pattern name],',','') != REPLACE(t.[Sawing Pattern name],',','')
);

Historical sum for current group

I have a SQL database with people, from which I want to see how much experience each person has in a specific department.
In the current query I have the following code:
SELECT [PERSON_ID]
,sum(case when [DEPARTMENT] = 'Marketing' then 1 else 0 end) as Exp_Marketing
,sum(case when [FUNCTION_DESC] = 'Finance' then 1 else 0 end) as Exp_Finance
FROM [xxxx].[xxxx].[xxxx]
GROUP BY [PERSON_ID]
Each person has one row for the months of service, so a person with 12 months of experience in Finance has a value of 12 in the Exp_Finance column.
The issue however is that the result now shows the outcome for all people. Also the one who already left the organization. How can I make sure the result only shows the historical information for the people currently part in the organization. In other words, the ones actually having a row with "2018M06" as value for the Date column.
You can use a having clause:
SELECT [PERSON_ID],
sum(case when [DEPARTMENT] = 'Marketing' then 1 else 0 end) as Exp_Marketing,
sum(case when [FUNCTION_DESC] = 'Finance' then 1 else 0 end) as Exp_Finance
FROM [xxxx].[xxxx].[xxxx]
GROUP BY [PERSON_ID]
HAVING MAX([DATE]) = '2018M06';
Your month format seems amenable to using MAX().
You should add an EXISTS within a WHERE clause so you only include people meeting your criteria.
SELECT [PERSON_ID]
,sum(case when [DEPARTMENT] = 'Marketing' then 1 else 0 end) as Exp_Marketing
,sum(case when [FUNCTION_DESC] = 'Finance' then 1 else 0 end) as Exp_Finance
FROM [xxxx].[xxxx].[xxxx] A
WHERE EXISTS (SELECT * FROM [xxxx].[xxxx].[xxxx] B
WHERE A.PERSON_ID = B.PERSON_ID AND B.[DATE] = '2018M06')
GROUP BY [PERSON_ID]

Count total number of records based on answers

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