I have a query that works fine on PostgreSQl v12.3.
SELECT player01, player02, COUNT(*) AS score_count
FROM results
GROUP BY player02, player01
ORDER BY score_count DESC, player01 ASC
LIMIT 10
;
What I want to achieve is to return the score_count of the player combinations that is greater than 4 (or greater as the season progresses)
Using a WHERE statment at the end of the query I get the following error.
SELECT player01, player02, COUNT(*) AS score_count
FROM results
GROUP BY player02, player01
ORDER BY score_count DESC, player01 ASC
WHERE score_count > 4
;
ERROR: syntax error at or near "WHERE"
LINE 5: WHERE score_count > 4
Placing a WHERE statement within the query I get the following error.
SELECT player01, player02, COUNT(*) AS score_count
FROM results
WHERE score_count > 4
GROUP BY player02, player01
ORDER BY score_count DESC, player01 ASC
;
ERROR: column "score_count" does not exist
LINE 3: WHERE score_count > 4
And also
SELECT star01, star02, COUNT(*) AS num_count
FROM results
WHERE count(*) > 4
GROUP BY star02, star01
ORDER BY num_count DESC, star01 ASC
;
ERROR: aggregate functions are not allowed in WHERE
LINE 3: WHERE count(*) > 4
I have tried other combinations that return one or other of these errors. HAVING score_count > 4 produces the same errors.
Or is there a better/alternative way to do this?
HAVING score_count > 4 produces the same errors.
No, it doesn't. You just have to move the clause after GROUP BY:
SELECT star01, star02, count(*) AS num_count
FROM results
GROUP BY star01, star02
HAVING count(*) > 4 -- here !
ORDER BY num_count DESC, star01;
Related
Calculate the first actual bought item and populate the first_actual_item column in tr2_invoice.
SELECT cust_id, total_amount, items, MIN(time_in)
FROM tr_invoice WHERE total_amount <> 0
GROUP BY cust_id;
ERROR: column "tr_invoice.total_amount" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT cust_id, total_amount, items, MIN...
I used AVG(), MIN(), MAX(), or ARRAY_AGG() as aggregations for total_amount and items, it would output differently from what I queried on MySQL. Any better solution to solve this?
the selected fields must appear in the GROUP BY clause.
1.
SELECT cust_id, total_amount, items, MIN(time_in) over( PARTITION by cust_id) as min_time_in
FROM tr_invoice WHERE total_amount <> 0 ;
2.
SELECT
b.cust_id ,
b.total_amount,
b.items ,
a.min_time_in
from
(
SELECT
cust_id,
MIN(time_in) as min_time_in
FROM
tr_invoice
WHERE
total_amount <> 0
GROUP BY
cust_id
)a
join
tr_invoice b
ON
a.cust_id=b.cust_id;
Please refer link
I just started learning Postgres, and I'm trying to make an aggregation table that has the columns:
user_id
booking_sequence
booking_created_time
booking_paid_time
booking_price_amount
total_spent
All columns are provided, except for the booking_sequence column. I need to make a query that shows the first five flights of each user that has at least x purchases and has spent more than a certain amount of money, then sort it by the amount of money spent by the user, and then sort it by the booking sequence column.
I've tried :
select user_id,
row_number() over(partition by user_id order by user_id) as booking_sequence,
booking_created_time as booking_created_date,
booking_price_amount,
sum(booking_price_amount) as total_booking_price_amount
from fact_flight_sales
group by user_id, booking_created_time, booking_price_amount
having count(user_id) > 5
and total_booking_price_amount > 1000
order by total_booking_price_amount;
I got 0 when I added count(user_id) > 5, and total_booking_price_amount is not found when I add the second condition in the HAVING clause.
Edit:
I managed to make the code function correctly, for those who are curious:
select x.user_id, row_number() over(partition by x.user_id)
as booking_sequence, x.booking_created_time::date as booking_created_date, x.booking_price_amount,
sum(y.booking_price_amount) as total_booking_price_amount from
(
select user_id, booking_created_time, booking_price_amount from fact_flight_sales
group by user_id, booking_created_time, booking_price_amount
) as x
join
(
select user_id, booking_price_amount
from fact_flight_sales group by user_id, booking_price_amount
) as y
on x.user_id = y.user_id
group by x.user_id, x.booking_created_time, x.booking_price_amount
having count(x.user_id) >= 1 and sum(y.booking_price_amount) >250000
order by total_booking_price_amount desc, booking_sequence asc;
Big thanks to Laurenz for the help!
About count(user_id) > 5:
HAVING is calculated before window functions are evaluated, So result rows excluded by the HAVING clause will not be used to calculate the window function.
About total_booking_price_amount in HAVING:
You cannot use aliases from the SELECT list in the HAVING clause. You will have to repeat the expression (or use a subquery).
I am writing a simple SQL query to get the latest record from every customer and to get the max of device_count if there are multiple records for a customer with same timestamp. However, the max function doesn't seem to take the max value though. Any help would be appreciated.
My SQL query -
select sub.customerid, max(sub.device_count) from(
SELECT customerid, device_count,
RANK() OVER
(
PARTITION by customerid
ORDER BY date_time desc
) AS rownum
FROM tableA) sub
WHERE rownum = 1
group by 1
Sample data:
customerid
device_count
date_time
A
3573
2021-07-26 02:15:09-05:00
A
4
2021-07-26 02:15:13-05:00
A
16988
2021-07-26 02:15:13-05:00
A
20696
2021-07-26 02:15:13-05:00
A
24655
2021-07-26 02:15:13-05:00
Desired Output should be to get the row with max device_count which is 24655 but I get 16988 as the output.
try to :
sort your table using ORDER BY customerid,device_count
Then apply the LAST_VALUE(device_count) window function aver the customerid partition.
Apply LAST_VALUE() to find the latest device_count (since it's sorted ascending, the last device_count value is the max).
You need to put device_count into the window function's order by and take out the aggregation:
select sub.customerid, device_count from(
SELECT customerid, device_count,
RANK() OVER
(
PARTITION by customerid
ORDER BY date_time desc, device_count desc
) AS rownum
FROM tableA) sub where rownum=1;
But if the top row for a customerid has ties (in both date_time and device_count fields) it will return all such ties. So better to replace RANK() with ROW_NUMBER().
SELECT partner_id
FROM trip_delivery_sales ts
WHERE ts.route_id='152'
GROUP BY ts.partner_id
From the query we can get the partners id.Using that partner id we want check in trip delicery sales lines table and want to find each customer last two sale product quantity sum. If last two sale have product qty as 2 & 5 want result as partner_id | count as Mn2333 - 7
here fore example i take partner id as 34806. But i want to check all partner_id obtained from last query
SELECT product_qty
FROM trip_delivery_sales_lines td
WHERE td.partner_id='34806'
AND td.route_id='152'
AND td.product_id='432'
ORDER BY td.order_date DESC
LIMIT 2
You can run this query
SELECT td.partner_id,sum(product_qty)
FROM trip_delivery_sales_lines td,
(SELECT partner_id FROM trip_delivery_sales ts WHERE ts.route_id='152') as ts
WHERE td.partner_id=ts.partner_id
AND td.product_id='432'
GROUP BY td.partner_id
ORDER BY td.order_date DESC
LIMIT 2
Or this one
with ts as (SELECT distinct partner_id FROM trip_delivery_sales WHERE route_id='152')
SELECT td.partner_id,sum(product_qty)
FROM trip_delivery_sales_lines td,ts
WHERE td.partner_id=ts.partner_id
AND td.product_id='432'
GROUP BY td.partner_id
ORDER BY td.order_date DESC
LIMIT 2
You might be looking for
SELECT DISTINCT ts.partner_id, ARRAY(
SELECT product_qty
FROM trip_delivery_sales_lines td
WHERE td.partner_id=ts.partner_id
AND td.product_id='432'
ORDER BY td.order_date DESC
LIMIT 2
) AS product_qty_arr
FROM trip_delivery_sales ts
WHERE ts.route_id='152'
or just
SELECT
partner_id,
array_agg(product_qty ORDER BY order_date DESC) as product_qty_arr
FROM (
SELECT
td.partner_id,
td.product_qty,
td.order_date,
row_number() OVER (PARTITION BY td.partner_id ORDER BY td.order_date DESC)
FROM trip_delivery_sales_lines td
JOIN trip_delivery_sales ts USING (partner_id)
WHERE ts.route_id='152'
AND td.product_id='432'
) AS enumerated
WHERE row_number <= 2
GROUP BY partner_id
See also PostgreSQL: top n entries per item in same table or Optimize GROUP BY query to retrieve latest row per user
I have this select statement in SQL Server Management Studio 2014:
SELECT main.car_descr
,vari.engineCode
,count(*) over(partition by vari.engineCode) as quant
FROM dbspareparts.dbo.stock as stock
inner join fiord.dbo.store as main on stock.[id_store]=main.[id_store]
where quant>2
order by quant desc
when I execute, I get "invalid column name" on the istruction
where quant>2
Why and how can I get this work?
I need to use the count(*) over(...) statement, cause this is only a piece of another longer query.
Thanks!
select * from (SELECT main.car_descr
,vari.engineCode
,count(*) over(partition by vari.engineCode) as quant
FROM dbspareparts.dbo.stock as stock
inner join fiord.dbo.store as main on stock.[id_store]=main.[id_store]) as tbl
where quant>2
order by quant desc
the quant isn't bound as a variable until after your query returns, and so you'll need to wrap it in an inner query before you can filter by it.