SQLDev limiting results - oracle-sqldeveloper

TIA for any help/advice/further reading.
I'm trying to make SQLDev do a count of how many packages customers have had and then only show the top 10 of those results.
So I have this....
select pickup_customer , count (pickup_customer)
from
( select pickup_customer, count (pickup_customer)
from manifest
order by count (pickup_customer) desc )
where ROWNUM <= 10
group by pickup_customer
order by count (pickup_customer) desc
With that I'm getting 'Not a single group function' and I can't figure out where it's gone wrong. Probably very simple fix, I just can't see it right now!
EDIT: I have tried this code but am getting a 'missing right parenthesis ' error now!
select pickup_customer , count (pickup_customer)
from
(select pickup_customer, count (pickup_customer) --sub-query which pre-orders the results for rownum to then limit.
from manifest
order by count (pickup_customer) desc
group by pickup_customer)
where ROWNUM <= 10 -- limits the results to be only the top 10

The following query should work.
SELECT pickup_customer, COUNT (pickup_customer)
FROM enrollment
WHERE ROWNUM <= 10
GROUP BY pickup_customer
ORDER BY COUNT (pickup_customer) DESC

Related

Postgresql Use a specified value instead of first_value

I am trying to replace first_value and use a specified value to use in an equation because of alpha sort I'm having an issue. I want to use a value in a row called 'control' which is in the segment column and direct_mail_test table. So I need to find a way to call just that value ('control') to then use in the equation. New to PostgreSQL, any help would be greatly appreciated.
Here is my current code
select segment,
count(*) as total,
count(b.c_guid) as bookings,
100.0 * count(b.c_guid)/count(*) as percent,
100.0 * count(b.c_guid) / first_value(count(b.c_guid)) over ( order by segment asc ) as comp
from mailing_tests
left join (
select distinct g.contact_guid as c_guid
from guest g
inner join booking
on booking.guid = g.booking_guid
where booking.book_date >= {{date_start}}
[[and booking.book_date < {{date_end}}]]
and booking.status in ('Booked')
) b
on mailing_tests.guid = b.c_guid
where {{project}}
group by segment
order by segment asc
Here is my output:
segment
total bookings percent comp
catalog 4,091 30 0.73 100
control 30,611 359 1.17 1,196.67
direct_mail 30,611 393 1.28 1,310
online_ads 30,611 371 1.21 1,236.67
'''
As of now its taking in the 'catalog' as the
measurable and I need it to take the 'control' as the
measurable.
Just to put some more context on the code, I am using
metabase. So the {{date_start}}
[[and peak15_booking.book_date < {{date_end}}]]
{{project}}
are all variable functions used in metabase.
I tried to use the nth_value, fetch function, and
many others, but I'm not sure if I am even using
those properly. I have been unsuccessful in finding
any answer to this.
I found a way to make this work, but not sure if it's the cleanest way to do this or if I will run into future issues. I still haven't figured out how to replace first_value, but I did add (order by segment='control' desc) twice. once in the SELECT statement and the other in WHERE clause. Again, not sure if this is the correct way to do this, but thought I would show that I did end up figuring it out. Not sure if I should of answered my own question or deleted it, but thought that this might help someone else.
'
select segment,
count(*) as total,
count(b.c_guid) as bookings,
100.0 * count(b.c_guid) / count(*) as percent,
100.0 * count(b.c_guid) / first_value(count(b.c_guid)) over ( order by segment='control' desc, segment asc ) as comp
from mailing_tests
left join (
select distinct g.contact_guid as c_guid
from guest g
inner join booking
on booking.guid = g.booking_guid
where booking.book_date >= {{date_start}}
[[and booking.book_date < {{date_end}}]]
and booking.status in ('Booked')
) b
on mailing_tests.guid = b.c_guid
where {{project}}
group by segment
order by segment='control' desc, segment asc
'

How to find duplicate values after distinct count

One piece of code:
select count(distinct for_id),task_text ,status from core.vw_task_new
where code = 'willingness_assessment' and status in ('Completed','Ready') and task_text is not null and dt > '2022-07-18'
group by task_text ,status
gives 647 as the total count.
however the code below:
select count(distinct for_id) from core.vw_task_new
where code = 'willingness_assessment' and status in ('Completed','Ready') and task_text is not null and dt > '2022-07-18'
gives 630 as the count
My question is, how do I get the duplicates that are causing this discrepancy?
May be below query might help you:
select task_text ,status,count(1) from core.vw_task_new
where code = 'willingness_assessment' and status in
('Completed','Ready') and task_text is not null and dt > '2022-07-18'
group by task_text ,status having count(1) > 1
having count(1)>1 returns all the which existed more than once with the combination mentioned in SELECT and GROUP BY clause

postgreSQL, first date when cummulative sum reaches mark

I have the following sample table
And the output should be the first date (for each id) when cum_rev reaches the 100 mark.
I tried the following, because I taught with group bz trick and the where condition i will only get the first occurrence of value higher than 100.
SELECT id
,pd
,cum_rev
FROM (
SELECT id
,pd
,rev
,SUM(rev) OVER (
PARTITION BY id
ORDER BY pd
) AS cum_rev
FROM tab1
)
WHERE cum_rev >= 100
GROUP BY id
But it is not working, and I get the following error. And also when I add an alias is not helping
ERROR: subquery in FROM must have an alias LINE 4: FROM (
^ HINT: For example, FROM (SELECT ...) [AS] foo.
So the desired output is:
2 2015-04-02 135.70
3 2015-07-03 102.36
Do I need another approach? Can anyone help?
Thanks
demo:db<>fiddle
SELECT
id, total
FROM (
SELECT
*,
SUM(rev) OVER (PARTITION BY id ORDER BY pd) - rev as prev_total,
SUM(rev) OVER (PARTITION BY id ORDER BY pd) as total
FROM tab1
) s
WHERE total >= 100 AND prev_total < 100
You can use the cumulative SUM() window function for each id group (partition). To find the first which goes over a threshold you need to check the previous value for being under the threshold while the current one meets it.
PS: You got the error because your subquery is missing an alias. In my example its just s

Inner join removed from the SQL query

I have a below SQL query to get the three records for notifying purpose.
SELECT orders.msg
FROM orders
INNER JOIN
(
SELECT id
FROM orders
WHERE type_id = 12
ORDER BY id DESC LIMIT 3 OFFSET 0
) AS items
ON orders.id = items.id;
When trying to make the query optimized, i made the changes as below.
SELECT orders.msg
FROM orders
WHERE type_id = 12
ORDER BY id DESC LIMIT 3 OFFSET 0;
Is the modified query seems to be OK or did i miss anything here or any other way of doing is there??
The simplified version on the bottom looks logically identical, to me, to the one on top:
SELECT msg
FROM orders
WHERE type_id = 12
ORDER BY id DESC LIMIT 3;
Note that the above query could benefit from the following index:
CREATE INDEX idx ON orders (type_id, id, msg);
This index would completely cover the WHERE, ORDER BY, and SELECT clauses.
You can try this also:
SELECT orders.msg
FROM orders
WHERE orders.id
IN (
SELECT id
FROM orders
WHERE type_id = 12
ORDER BY id
DESC LIMIT 3 OFFSET 0
)

PostgreSQL: select column and exclude from group

This question has probably been asked in different formats, but I could not find the answer.
I have table orders
date, quantity_ordered, unit_cost_cents , product_model_number, title
I would like to:
SELECT
model_number,
title,
SUM(unit_cost_cents / 100.00 * quantity_ordered) as total
FROM orders
GROUP BY model_number
HAVING SUM(quantity_submitted) > 0
ORDER BY total DESC
But it requires grouping by the title as well.
My problem being is that my title changes over time. I'd like to preserve the titles and simply display/select the most recent title without grouping by title which would make the numbers different.
You can use a subquery to fetch the latest title:
SELECT
model_number,
(select max(title) from orders where date = (
select max(date) from orders where model_number = o.model_number)
) title,
SUM(unit_cost_cents / 100.00 * quantity_ordered) as total
FROM orders o
GROUP BY model_number
HAVING SUM(quantity_submitted) > 0
ORDER BY total DESC
I used select max(title) instead of select title to make sure that the subquery will not return more than 1 rows (just in case).
SELECT
o.model_number
, om.title
, SUM(o.unit_cost_cents / 100.00 * o.quantity_ordered) as total
FROM orders o
JOIN (SELECT model_number, title
,row_number() OVER (PARTITION BY model_number ORDER BY zdate DESC) AS rn
FROM orders) om
ON om.model_number=o.model_number AND om.rn=1
GROUP BY 1,2
HAVING SUM(o.quantity_submitted) > 0
ORDER BY 3 DESC
;