How To Select Top Value - sqlplus

SELECT B.CustomerID, SUM(C.UnitPrice * C.Quantity) AS "Total Value"
FROM Orders B, Order_Det C
WHERE B.OrderID = C.OrderID AND “Total Value” = (SELECT MAX(“Total Value”) FROM Order_Det)
GROUP BY B.CustomerID
ORDER BY "Total Value";
the following code from the above is what i'd tried.
A customer able to make MULTIPLE orders. thus, i want to display the most valuable customer by sum of multiple their quantity purchases and unit price.
The problem i faced is i was unable to archive who is the most valuable customer. Please guide me. Tq

here it is!!
SELECT O.CustomerID, SUM(OD.Quantity*OD.UnitPrice) AS "Total Value"
FROM Orders O
INNER JOIN Order_Det OD ON O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice)
or
SELECT O.CustomerID, SUM(OD.Quantity*OD.UnitPrice) AS "Total Value"
FROM Orders O, Order_Det OD
WHERE O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice)
and for most valuable customer,
SELECT TOP 1 O.CustomerID
FROM Orders O
INNER JOIN Order_Det OD ON O.OrderId = OD.OrderId
GROUP BY O.CustomerID
ORDER BY SUM(OD.Quantity*OD.UnitPrice) DESC

Related

JOIN SQL query with two tables

SELECT u.id, u.name, u.surname, p.id as p_id, SUM(t.summa)
FROM users u
LEFT JOIN pupils p ON p.userid = u.id
LEFT JOIN tulovlar t ON t.pupilid = p.id
WHERE u.turi = 3
GROUP BY u.id
ORDER BY u.surname
sql response is showing this error
#1055 - Expression #4 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'crm_test.p.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

Trying to fetch data from table with good performance

I am trying to fetch customer and owner data
customer
|cnumber |id |
|080204220 |32859471000|
|907501981|6029151000|
role
|id|type|
|32859471000|owner|
|6029151000|customer|
result set
id|number|owner number|type|
|32859471000|080204220 |080204220 | owner
|6029151000|907501981|080204220 |customer
query
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';
This query gives proper result, but left outer join with same tables may cause impact on performance, is there any other way to achieve this?
I would prefer you to go with this only.
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';
As far as I can get the logic, you need to display an "owner"-customer among all of the others.
Since there is only one owner in the example data, I'd do it using the "cross join" (cartesian join)
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
cross join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id where r.roletype='owner') sub
select c.id,sub.cnumber,c.cnumber, r.roletype
from customer c
inner join role r on c.id = r.id
left outer join (select c.cnumber ,r.roletype,c.id
from customer c
INNER JOIN role r
ON c.id = r.id ) sub on sub.roletype='owner';

RIGHT OUTER JOIN returns empty results with WHERE

I need to produce a report of all records (businesses) created by a particular user each month over last months. I produced the following query and expect it to provide me with a row for each month. However, this user didn't create any records (businesses) these months so I get an empty result [].
I'm still expecting to receive a row for each month, since I'm selecting a generate_series column using RIGHT OUTER JOIN but it doesn't happen.
start = 3.months.ago
stop = Time.now
new_businesses = Business.select(
"generate_series, count(id) as new").
joins("RIGHT OUTER JOIN ( SELECT
generate_series(#{start.month}, #{stop.month})) series
ON generate_series = date_part('month', created_at)
").
where(created_at: start.beginning_of_month .. stop.end_of_month).
where(author_id: creator.id).
group("generate_series").
order('generate_series ASC')
How can I change my query to get a row for each month instead of an empty result? I'm using PosgreSQL.
UPDATE
This code works:
new_businesses = Business.select(
"generate_series as month, count(id) as new").
joins("RIGHT OUTER JOIN ( SELECT
generate_series(#{start.month}, #{stop.month})) series
ON (generate_series = date_part('month', created_at)
AND author_id = #{creator.id}
AND created_at BETWEEN '#{start.beginning_of_month.to_formatted_s(:db)}' AND
'#{stop.end_of_month.to_formatted_s(:db)}'
)
").
group("generate_series").
order('generate_series ASC')
Your problem is in the where part which is breaks any outer joins. Consider the example:
select *
from a right outer join b on (a.id = b.id)
It will returns all rows from b and linked values from a, but:
select *
from a right outer join b on (a.id = b.id)
where a.some_field = 1
will drops all rows where a is not present.
The right way to do such sings is to place the filter into the join query part:
select *
from a right outer join b on (a.id = b.id and a.some_field = 1)
or use subquery:
select *
from (select * from a where a.some_field = 1) as a right outer join b on (a.id = b.id)

Count and Sum in Join sub query - can I build this sql query using ActiveRecord?

I am learning ActiveRecord. Can I build this query?
#sales_by_product = ActiveRecord::Base.connection.execute("SELECT
it.name,
it.id,
it.seller_id,
pur.volume,
pur.sales
FROM items it
INNER JOIN (SELECT
item_id,
COUNT(*) AS volume,
SUM(price) AS sales,
workflow_state AS state
FROM purchases
WHERE workflow_state = 'payment_successful'
GROUP BY item_id,
workflow_state) pur
ON pur.item_id = it.id
WHERE it.seller_id = '" + current_user.id.to_s + "'")
I would like to use the AR api as much as possible but I have not yet gotten the above to work using just AR.
Thanks!
I don't think it is a good idea to use AR for this query. It seems fun at first, but becomes annoying. And, it will be difficult to change later.
You can create your own query builder:
def query_for current_user
<<-SQL
SELECT
it.name,
it.id,
it.seller_id,
pur.volume,
pur.sales
FROM items it
INNER JOIN (SELECT
item_id,
COUNT(*) AS volume,
SUM(price) AS sales,
workflow_state AS state
FROM purchases
WHERE workflow_state = 'payment_successful'
GROUP BY item_id,
workflow_state) pur
ON pur.item_id = it.id
WHERE it.seller_id = '" + current_user.id.to_s + "'")
SQL
end
#sales_by_product = ActiveRecord::Base.connection.execute( query_for( current_user ))

Left outer join query (i think)

I have two tables that look like this:
Products: id category name description active
Sales_sheets: id product_id link
product_id is a foreign key from the products id table
I wrote a prepared statement JOIN like this which works:
SELECT p.name, p.description, s.link FROM products AS p
INNER JOIN sales_sheets AS s ON p.id = s.product_id WHERE active=1 AND category=?
Basically a product can have a link to a PDF, but not every product will have a sales sheet. So if i try to bring up a product which doesn't have a sales sheet attached to it then it always returns no rows.
So i thought I'd have to use a LEFT OUTER JOIN in place of the INNER JOIN, but that returns no rows too, am I naming the tables in the wrong order? I've never had to use an OUTER join before?
SELECT p.name, p.description, s.link FROM products p
LEFT JOIN sales_sheets s ON p.id = s.product_id
WHERE active = 1 && category = ?

Resources