SQL grouping into ranges? - sql

I have a table "USER_ACTIVITY" like this:
USER_ID, LOGINS, CITY
1 2 NY
2 4 NY
3 10 NY
15 0 WS
...
And I want to have a result like this:
CITY, DEAD_USERS, LOW_ACTIVITY, HIGH_ACTIVITY
NY 0 2 1 ....
This is about normal Oracle-SQL in Exaplus.
I really do not know how I can specify ranges on my own. Thank you!

Use COUNT with a CASE expression:
SELECT City,
COUNT( CASE WHEN logins = 0 THEN 1 END ) AS dead,
COUNT( CASE WHEN logins BETWEEN 1 AND 3 THEN 1 END ) AS low_activity,
COUNT( CASE WHEN logins > 3 THEN 1 END ) AS high_activity
FROM user_activity
GROUP BY City

Related

Oracle SQL: Obtain count of distinct column values based on another column

Here is a sample data to explain my case,
CompanyInfo:
Name, Company, Location, Completed, Pending
Andy AA Home 4 2
Jim AA Office 3 3
Dahli AA Home 4 2
Monica AA Home 4 2
Chandler AA Home-Office 1 0
Ashley AA Home-Office 1 0
The last three columns have duplicated information and I am trying to obtain count of location, completed and pending which are bound to each other. So the output would look something like below,
Company, Count(Locations), Count( Completed+Pending > 0),
AA 3 3
Why Count( Completed+Pending > 0) is 3? there are just three unique combinations of Home, Office and home-office columns where sum of completed+pending is > 0.
I did try below, but it gives me (AA, 3, 6) since it is processing all the 6 rows to obtain the count.
select Company,
count(distinct Location),
SUM (
CASE
WHEN (Completed + Pending) > 0 THEN 1
ELSE 0
END)
AS Total
From CompanyInfo
group by Company;
Any pointers?
I think you want a conditional count(distinct):
select Company,
count(distinct Location),
count(distinct case when Completed + Pending > 0 then location end)
from CompanyInfo
group by Company;

Display Correct Row based on Candy Number

Goal:
If a person has two candy number, number 1 should always display first. No need to display candy number 2.
If a person does not have number 1, it should display number 2 instead.
Display all data
(int)(int) (nvarchar) (int)
Id fId Name Candy Number
---------------------------------
1 12 Kimn 1
2 12 Kimn 2
3 19 Lisa 1
4 15 John 2
5 16 Maria 2
6 16 Maria 1
7 17 Mao 2
Requested result:
Id fId Name Candy Number
---------------------------------
1 12 Kimn 1
3 19 Lisa 1
4 15 John 2
6 16 Maria 1
7 17 Mao 2
Problem:
It doesn't work so well for me to display it.
Tried using case and end in where statement but the code didn't fit to the purpose.
Any idea?
select *
from
table
where
candynumber =
CASE WHEN b.MatchType = 1
THEN 1
ELSE 2
END
Thank you!
This can be using row_number() window function:
select Id, fId, Name, Candy_Number from (
select your_table.*, row_number() over(partition by fId order by Candy_Number) as rn from your_table
) t
where rn = 1
order by id
This gives one row per fId, with lower Candy_Number.
You can try this :
SELECT candyWrapper.ID,
candyWrapper.FID,
outerHardCandy.Name,
outerHardCandy.Number
FROM (SELECT innerSoftCandy.Name,
CASE
WHEN (SUM(innerSoftCandy.Number) = 3) OR (SUM(innerSoftCandy.Number) = 1) THEN 1
WHEN (SUM(innerSoftCandy.Number) = 2) THEN 2
END AS Number
FROM Candy innerSoftCandy
GROUP BY innerSoftCandy.Name
) outerHardCandy
INNER JOIN Candy candyWrapper ON (outerHardCandy.Name = candyWrapper.Name AND outerHardCandy.Number = candyWrapper.Number)
ORDER BY candyWrapper.ID
You can see this here -> http://rextester.com/BBD89608

How to find number of failed grades and the number of general average?

I have A table of students and their grades.
How can I count the number of failed grades (<50)
and find the general average ( I mean the average for every student ) using sqlite?
this is the table (studentTable):
sID LessonID grade
1 1 45
1 2 50
1 3 65
2 1 44
2 2 22
2 3 91
I expect the results like this:
sID noOfFails Average
1 1 53
2 2 5
Try
SELECT
sID,
SUM(CASE WHEN grade < 50 THEN 1 ELSE 0 END) AS noOfFails,
AVG(grade) AS Average
FROM studentTable
GROUP BY sID
Demo at http://sqlfiddle.com/#!5/fcd13/1
You could use a case expression inside the count function:
SELECT sID, COUNT(CASE WHEN grade < 50 THEN 1 END) AS noOfFails, AVG(grade)
FROM mytable
You can simply run it as follows:
SELECT sID, COUNT(IIF(grade<50,1,NULL)) as noOfFails, AVG(grade) as Average
FROM studentTable GROUP BY sID

SQL: Combine Duplicate Rows And Case Statement Values in Final Data Output

I'm working on a SQL query that counts duplicate records that are based on a text field I am working with: where datasource = 'Web' or 'Internal'. I am currently using a case statement to count the number of times a record shows that value. My question is how do I combine the two results into one record that shows a count of both.
I'm attaching a query of what I currently have working, what my output is and what I would like the end result to look like.
SELECT id
,lastname
,firstname
,datasource
,CASE
WHEN (
(Datasource = 'Web')
)THEN Count(Datasource)
ELSE 0
END WebData
,CASE
WHEN (
(Datasource = 'Internal')
) THEN Count(Datasource)
ELSE 0
END InternalData
,count(id) as countid
FROM Table
GROUP BY
id
,lastname
,firstname
,datasource
This currently returns:
12345 Jack Boss Internal 0 1 1
12241 Eric Graves Internal 0 1 1
13300 Su Lynn Web 1 0 1
13300 Su Lynn Internal 0 1 1
13914 Mark Ross Internal 0 2 2
14008 Mitch Smith Internal 0 1 1
I would like it to return:
12345 Jack Boss 0 1 1
12241 Eric Graves 0 1 1
13300 Su Lynn 1 1 2
13914 Mark Ross 0 2 2
14008 Mitch Smith 0 1 1
Thanks
You need to add the outer select for current query with the Group on the the columsn you want to do the aggrigate.Just add the Outer select to your query,
SELECT
data.id,
data.lastname,
data.firstname,
SUM(data.WebData) AS WebData,
SUM(data.InternalData) AS InternalData,
SUM(data.countid) AS Countid
FROM
(
SELECT id,lastname,
firstname,datasource,
CASE WHEN Datasource = 'Web' THEN Count(Datasource) ELSE 0 END WebData,
CASE WHEN Datasource = 'Internal' THEN Count(Datasource)ELSE 0 END InternalData,
count(id) AS Countid
FROM Table
GROUP BY
id,lastname,firstname,datasource
) AS data
GROUP BY
data.id,data.firstname,data.lastname

SQL QUERY MERGE TWO ROW DATA

Suppose My Database is like this :
MemberName MemberID ResultsEligibilityID
Thuso 2 1
Thuso 2 1
Maubane 3 2
Maubane 3 1
CDeveloper 5 2
CDeveloper 5 2
Now is it possible to write a query to display (The Below output) based on this:
if both ResultsEligibilityID for a single Member is 1 then Eligibile,
Otherwise Non-Eligible.
OUTPUT
MemberName MemberID ResultsEligibilityID Results
Thuso 2 1 Eligible
Maubane 3 2 Non-Eligible
CDeveloper 5 2 Non-Eligible
Thanks in advance for the help.
Please try:
select
MemberName,
MemberID,
MAX(ResultsEligibilityID) ResultsEligibilityID ,
(case when sum(case when ResultsEligibilityID=1 then 1 else 0 end)= COUNT(*)
then 'Eligible' else 'Non-Eligible' end) Results
From
YourTable
group by MemberName,MemberID