How do i count number of consultated - sql

/16 Write a query to show the Staff Id, number of consultations. Name the new column Num of Consults./
COLUMN COUNT(dateconsulted) HEADING "Num of Consults"
SELECT staffid,
COUNT(dateconsulted)
FROM consultation;
ERROR at line 1: ORA-00937: not a single-group group function
it should count how many number of consults that has been completed
Edited i got it to work i hope but the next one is similar
/* Write a query to show the Staff id, number of consultations only for staff that have more than 2 consulation Name the new column Num of Consults
*/
/*come back to this double checking after */
COLUMN COUNT() HEADING "Num of Consults"
SELECT staffid,
COUNT()
FROM consultation
WHERE 'Num of Consults'> 2
GROUP BY staffid;
Result that i wanting is to just disply the Num Of consults that is greater > than 2 but for some reason it keep other record when i want to display just the record of more than 2

Please try this.
SELECT
staffid, COUNT(dateconsulted) as "Num of Consults"
FROM consultation
GROUP BY staffid;

Related

Using a WITH as an aggregate value

I am querying a Presto table where I want to calculate what percentage of the total a certain subset of the rows account for.
Consider a table like this:
id
m
1
5
1
7
2
9
3
8
I want to query to report how much of the total measure (m) is contributed by each id. In this example, the total of the measure column is 29 can I find it with a query like...
SELECT SUM("m") FROM t;
output:
sqlite> SELECT SUM("m") FROM t;
29
Then I want to subtotal by id for some of the ids like
SELECT "id", SUM("m") AS "sub_total" FROM t WHERE "id" IN ('1','3') GROUP BY id;
output:
sqlite> SELECT "id", SUM("m") AS "sub_total" FROM t WHERE "id" IN ('1','3') GROUP BY id;
1|12
3|8
Now I want to add a third column where the subtotals are divided by the grand total (29) to get the percentage for each selected id.
I tried:
sqlite>
WITH a AS (
SELECT SUM("m") AS g FROM t )
SELECT "id", SUM("m") AS "sub_total", SUM(m)*100/"a"."g"
FROM a, t
WHERE "t"."id" IN ('1','3') GROUP BY "t"."id";
output:
1|12|41
3|8|27
Which is all good in SQLLite3! But when I translate this to my actual Presto DB (and the right tables and columns), I get this error:
presto error: line 10:5: 'a.g' must be an aggregate expression or appear in GROUP BY clause
I can't understand what I'm missing here or why this would be different in Presto.
When you have a GROUP BY in your query, all expressions that the query is returning must be either:
the expression you are grouping by
or aggregate function
For example if you do GROUP BY id, the resulting query will return one row per id - you cannot just use m, because with id = 1 there are two values: 5 and 7 - so what should be returned? First value, last, sum, average? You need to tell it using aggregate function like sum(m).
Same with a.g - you need to add it to GROUP BY.
WITH a AS (
SELECT SUM("m") AS g FROM t )
SELECT "id", SUM("m") AS "sub_total", SUM(m)*100/"a"."g"
FROM a, t
WHERE "t"."id" IN ('1','3') GROUP BY "t"."id", "a"."g";
There's nothing special about PrestoDB here, it's more SQLite that's less strict, actually most other database engines would complain about your case.

Count with Group By always shows '1'

I'm trying to count the number of articles mentioning Donald Trump exist in a Google BigQuery table.
SELECT
sourcecommonname,
COUNT(DISTINCT sourcecommonname) counter
FROM
`israel_media`
WHERE
persons LIKE '%donald trump%'
GROUP BY
sourcecommonname
Results are always
sourcecommonname
counter
first_newspaper
1
second_newspaper
1
third_newspaper
1
forth_newspaper
1
What am I not seeing?
Of course. You are counting distinct values. But there is only one value per group. That is what the group by does.
Perhaps you just want count() without distinct:
SELECT sourcecommonname,
COUNT(*) as counter
FROM `israel_media`
WHERE persons LIKE '%donald trump%'
GROUP BY sourcecommonname

Postgresql: Query to know which fraction of the values are larger/smaller

I would like to query my database to know which fraction/percentage of the elements of a table are larger/smaller than a given value.
For instance, let's say I have a table shopping_list with the following schema:
id integer
name text
price double precision
with contents:
id name price
1 banana 1
2 book 20
3 chicken 5
4 chocolate 3
I am now going to buy a new item with price 4, and I would like to know where this new item will be ranked in the shopping list. In this case the element will be greater than 50% of the elements.
I know I can run two queries and count the number of elements, e.g.:
-- returns = 4
SELECT COUNT(*)
FROM shopping_list;
-- returns = 2
SELECT COUNT(*)
FROM shopping_list
WHERE price > 4;
But I would like to do it with a single query to avoid post-processing the results.
if you just want them in single query use UNION
SELECT COUNT(*), 'total'
FROM shopping_list
UNION
SELECT COUNT(*),'greater'
FROM shopping_list
WHERE price > 4;
The simplest way is to use avg():
SELECT AVG( (price > 4)::float)
FROM shopping_list;
One way to get both results is as follows:
select count(*) as total,
(select count(*) from shopping_list where price > 4) as greater
from shopping_list
It will get both results in a single row, with the names you specified. It does, however, involve a query within a query.
I found the aggregate function PERCENT_RANK which does exactly what I wanted:
SELECT PERCENT_RANK(4) WITHIN GROUP (ORDER BY price)
FROM shopping_list;
-- returns 0.5

sql count or sum?

I'm a newbie programmer, I want to sum a value of employee's attendance record
Anyway, what should I choose? COUNT or SUM?
I tried to use COUNT functions like this...
SELECT COUNT(jlh_sakit) AS sakit FROM rekap_absen
It shows value changed to "1" for 1 Record only.
And I try to use SUM functions like this...
SELECT SUM(jlh_sakit) AS sakit FROM rekap_absen
It shows all values changed ALL value to "1"
I want to display only 1 person for each sum
(e.g : John (2 sick, 2 permissions, 1 alpha)
Can you help me please?
If you are using any aggregate function like min/max/sum/count you should use group by. Now your question says "what should I choose? COUNT or SUM?" Assuming you have person_name, jlh_sakit which means sick/permission/alpha in your case you could use
select person_name, count(jhl_sakit) as attribute
from rekap_absen
group by person
This will give you output like:
person_name attribute
John 2
King 5
In order to sum by specified column, use group by statement.
SELECT SUM(sick),SUM(alpha),SUM(permissions),person FROM rekap_absen group by person
It will group your sums according to person.
You may name your sums like:
SELECT SUM(sick) as sick,SUM(alpha) as alpha,SUM(permissions) as permissions,person FROM rekap_absen group by person
Assuming that you have table rekap_absen with columns: person,sick,alpha,permissions

Find the next record by date for a person and compare it to their initial record

I have a moderate sized table (tbl) with:
id,
person_id,
date,
resultA,
resultB,
resultC,
resultD
with about 20000 results.
Each id of the table corresponds to a person's result in 4 different tests and their person_id.
e.g.
id 1
person_id 2 (Joe Bloggs (made up name))
result on date (01/01/2012)
A positive,
B negative,
C negative,
D negative
I need to perform a query where it selects the records where one of the results was positive and the remainder negative. EASY!
SELECT id, person_id, date, resultA, resultB, resultC, resultD
FROM tbl
WHERE resultA = "P" AND resultB = "N" AND resultC = "N" AND resultD = "N"
The tricky bit is that I want to find out what the NEXT result for that person, by date, is for each of the records that meet the criteria above. I then want to compare the two results and see if the results have changed. i.e. resultB might change from "N" to "P" in the say, 1 month, between Joe Bloggs (made up name) results and I need to capture that.
I am sure I need to use subqueries in access 2010 but I can't quite work out how to do it.
I have changed date to a date, because date is a reserved word. This only returns an extra column for ResultA, but the subquery can be repeated for each result.
SELECT a.id,
a.person_id,
a.adate,
a.resulta,
a.resultb,
a.resultc,
a.resultd,
(SELECT TOP 1 b.resulta
FROM tbl b
WHERE b.person_id = a.person_id
AND b.adate > a.adate
ORDER BY b.adate, b.id) AS res
FROM tbl AS a
WHERE a.resulta = "P"
AND a.resultb = "N"
AND a.resultc = "N"
AND a.resultd = "N"
I have edited ORDER BY b.adate to include b.id, as per comments. Access returns matched records and if a person has more than one record on the same date, more than one record will be returned by Top 1.