Oracle SQL Count function - sql

I am hoping someone can advise on the below please?
I have some code (below), it is pulling the data I need with no issues. I have been trying (in vain) to add a COUNT function in here somewhere. The output I am looking for would be a count of how many orders are assigned to each agent. I tried a few diffent things based on other questions but can't seem to get it correct. I think I am placing the COUNT 'Agent' statement and the GROUP BY in the wrong place. Please can someone advise? (I am using Oracle SQL Developer).
select
n.ordernum as "Order",
h.employee as "Name"
from ordermgmt n, orderheader h
where h.ordernum = n.ordernum
and h.employee_group IN ('ORDER.MGMT')
and h.employee is NOT NULL
and n.percentcomplete = '0'
and h.order_status !='CLOSED'
Output I am looking for would be, for example:
Name Orders Assigned
Bob 3
Peter 6
John 2
Thank you in advance
Name
Total
49
49
49
49
49
John
4
John
4
John
4
John
4
Peter
2
Peter
2
Bob
3
Bob
3
Bob
3
for example. so there are 49 blank rows summed up as 49 in the Total column. I did not add the full 49 blank columns to save space

Would be easier with sample data and expected output, but maybe you are looking for something like this
select
n.ordernum as "Order",
h.employee as "Name",
count(*) over (partition by h.employee) as OrdersAssigned
from ordermgmt n, orderheader h
where h.ordernum = n.ordernum
and h.employee_group IN ('ORDER.MGMT')
and h.employee is NOT NULL
and n.percentcomplete = '0'
and h.order_status !='CLOSED'

The use of COUNT (as other aggregate functions) is simple.
If you want to add an aggregate function, please group all scalar fields in the GROUP BY clause.
So, in the SELECT you can manage field1, field2, count(1) and so on but you must add in group by (after where conditions) field1, field2
Try this:
select
h.employee as "Name",
count(1) as "total"
from ordermgmt n, orderheader h
where h.ordernum = n.ordernum
and h.employee_group IN ('ORDER.MGMT')
and h.employee is NOT NULL
and n.percentcomplete = '0'
and h.order_status !='CLOSED'
GROUP BY h.employee

Related

SQL aggregate similar records

I have a dataset that I need to query from and aggregate the selected records based on a string similarity.
For example a simple SELECT, COUNT query can return a set of records like:
NAME
COUNT
CAR
6
CAR 1
12
CAR 22
2
CAR 45
9
Van 2
4
Van 22
5
Van 12
16
UNKNOWN
6
I want the result to be aggregate by a substring as:
NAME
COUNT
CAR
29
VAN
25
UNKOWN
6
A sample of the current query I have is:
SELECT "vehicle_name" AS "NAME", count(*) AS "Count"
FROM "vehicles"
WHERE ("registered" = 'true'GROUP BY "public"."players"."device_name"
ORDER BY "vehicle_name" ASC
You can use the metabase regexextract function to solve your problem, matching the first word by exploiting the start of string symbol.
SELECT REGEXEXTRACT([NAME], "^[A-Za-z]+") AS "NAME",
SUM([COUNT]) AS "COUNT"
FROM vehicles
GROUP BY REGEXEXTRACT([NAME], "^[A-Za-z]+")
Does it solve your problem?
Please try like this
SELECT
SUM(COUNT),
SUBSTRING(vehicle_name,1,ISNULL(NULLIF(PATINDEX('%[^A-Za-z.''0-9]%',LTRIM(RTRIM(vehicle_name))),0)-1,LEN(vehicle_name))) AS Value
FROM
vehicles
GROUP BY SUBSTRING(vehicle_name,1,ISNULL(NULLIF(PATINDEX('%[^A-Za-z.''0-9]%',LTRIM(RTRIM(vehicle_name))),0)-1,LEN(vehicle_name)))

Select row with shortest string in one column if there are duplicates in another column?

Let's say I have a database with rows like this
ID PNR NAME
1 35 Television
2 35 Television, flat screen
3 35 Television, CRT
4 87 Hat
5 99 Cup
6 99 Cup, small
I want to select each individual type of item (television, hat, cup) - but for the ones that have multiple entries in PNR I only want to select the one with the shortest NAME. So the result set would be
ID PNR NAME
1 35 Television
4 87 Hat
5 99 Cup
How would I construct such a query using SQLite? Is it even possible, or do I need to do this filtering in the application code?
Since SQLite 3.7.11, you can use MIN() or MAX() to select a row in a group:
SELECT ID,
PNR,
Name,
min(length(Name))
FROM MyTable
GROUP BY PNR;
You can use MIN(length(name))-aggregate function to find out the minimum length of several names; the slightly tricky thing is to get corresponding ID and NAME into the result. The following query should work:
select mt1.ID, mt1.PNR, mt1.Name
from MyTable mt1 inner join (
select pnr, min(length(Name)) as minlength
from MyTable group by pnr) mt2
on mt1.pnr = mt2.pnr and length(mt1.Name) = mt2.minlength

Tricky aggregation Oracle 11G

I am using Oracle 11G.
Here is my data in table ClassGrades:
ID Name APlusCount TotalStudents PctAplus
0 All 44 95 46.31
1 Grade1A 13 24 54.16
2 Grade1B 11 25 44.00
3 Grade1C 8 23 34.78
4 Grade1D 12 23 52.17
The data (APlusCount,TotalStudents) for ID 0 is the sum of data for all classes.
I want to calculate how each class compares to other classes except itself.
Example:
Take Grade1A that has PctAplus = 54.16.
I want to add all values for Grade1B,Grade1C and Grade1D which is;
((Sum of APlusCount for Grade 1B,1C,1D)/(Sum of TotalStudents for Grade 1B,1C,1D))*100
=(31/71)*100=> 43.66%
So Grade1A (54.16%) is doing much better when compared to its peers (43.66%)
I want to calculate Peers collective percentage for each Grade.
How do I do this?
Another approach might be to leverage the All record for totals (self cross join as mentioned in the comments), i.e.,
WITH g1 AS (
SELECT apluscount, totalstudents
FROM grades
WHERE name = 'All'
)
SELECT g.name, 100*(g1.apluscount - g.apluscount)/(g1.totalstudents - g.totalstudents)
FROM grades g, g1
WHERE g.name != 'All';
However I think that #Wernfried's solution is better as it doesn't depend on the existence of an All record.
UPDATE
Alternately, one could use an aggregate along with a GROUP BY in the WITH statement:
WITH g1 AS (
SELECT SUM(apluscount) AS apluscount, SUM(totalstudents) AS totalstudents
FROM grades
WHERE name != 'All'
)
SELECT g.name, 100*(g1.apluscount - g.apluscount)/(g1.totalstudents - g.totalstudents)
FROM grades g, g1
WHERE g.name != 'All';
Hope this helps. Again, the solution using window functions is probably the best, however.
I don't know how to deal with "All" record but for the others this is an approach:
select Name,
100*(sum(APlusCount) over () - APlusCount) /
(sum(TotalStudents) over () - TotalStudents) as result
from grades
where name <> 'All';
NAME RESULT
=================================
Grade1A 43.661971830986
Grade1B 47.142857142857
Grade1C 50
Grade1D 44.444444444444
See example in SQL Fiddle

Counting the number of rows based on like values

I'm a little bit lost on this. I would like to list the number of names beginning with the same letter, and find the total amount of names containing that first same letter.
For instance:
name | total
-------|--------
A | 12
B | 10
C | 8
D | 7
E | 3
F | 2
...
Z | 1
12 names beginning with letter 'A', 10 with 'B' and so on.
This is what I have so far
SELECT
LEFT(customers.name,1) AS 'name'
FROM customers
WHERE
customers.name LIKE '[a-z]%'
GROUP BY name
However, I'm unsure how I would add up columns based on like values.
This should work for you:
SELECT
LEFT(customers.name,1) AS 'name',
COUNT(*) AS NumberOfCustomers
FROM customers
WHERE
customers.name LIKE '[a-z]%'
GROUP BY LEFT(customers.name,1)
EDIT: Forgot the explanation; as many have mentioned already, you need to group on the calculation itself and not the alias you give it, as the GROUP BY operation actually happens prior to the SELECT and therefore has no idea of the alias yet. The COUNT part you would have figured out easily. Hope that helps.
You don't want to count the names, but only the first letters. So you must not group by name, but group by the first letter
SELECT LEFT(name, 1) AS name, count(*)
FROM customers
GROUP BY LEFT(name, 1)
SQLFiddle

SQL server - How to find the highest number in '<> ' in a text column?

Lets say I have the following data in the Employee table: (nothing more)
ID FirstName LastName x
-------------------------------------------------------------------
20 John Mackenzie <A>te</A><b>wq</b><a>342</a><d>rt21</d>
21 Ted Green <A>re</A><b>es</b><1>t34w</1><4>65z</4>
22 Marcy Nate <A>ds</A><b>tf</b><3>fv 34</3><6>65aa</6>
I need to search in the X column and get highest number in <> these brackets
What sort of SELECT statement can get me, for example, the number 6 like in <6>, in the x column?
This type of query generally works on finding patterns, I consider that the <6> is at the 9th position from left.
Please note if the pattern changes the below query will not work.
SELECT A.* FROM YOURTABLE A INNER JOIN
(SELECT TOP 1 ID,Firstname,Lastname,SUBSTRING(X,LEN(X)-9,1) AS [ORDER]
FROM YOURTABLE
WHERE ISNUMERIC(SUBSTRING(X,LEN(X)-9,1))=1
ORDER BY SUBSTRING(X,LEN(X)-9,1))B
ON
A.ID=B.ID AND
A.FIRSTNAME=B.FIRSTNAME AND
A.LASTNAME=B.LASTNAME