I am trying to convert following SQL into rails active record query
"SELECT * FROM stocks
INNER JOIN
(
SELECT product_id, MIN(ask_price) min_price
FROM stocks
GROUP BY product_id,size
) sub ON stocks.product_id = sub.product_id AND
stocks.ask_price = sub.min_price
where stocks.product_id = 1"
This query fetches the lowest price of the stock group by product and size of product.
So far I have tried to translate it like this it not right.
sub_query = Stock.select("product_id, MIN(ask_price) min_price").group(:product_id,:size)
stocks = Stock.joins("#{sub_query} stocks.product_id = sub.product_id AND
stocks.ask_price = sub.min_price")
You should pass into joins method all your join clause if you want to do some custom joining, like this:
stocks = Stock.joins(<<-SQL
INNER JOIN
(
SELECT product_id, MIN(ask_price) min_price
FROM stocks
GROUP BY product_id, size
) sub ON stocks.product_id = sub.product_id AND stocks.ask_price = sub.min_price
SQL).where(product_id: 1)
Related
I am trying to update two columns within a table from a select statment in MySQL 5.7.
The error I get is "invalid use of group function"
Stmt:
UPDATE
catalog mpc
JOIN
reviews mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET
mpc.RATING = avg(mpr.rating),
mpc.RATINGS = count(mpr.rating)
WHERE
mpr.MERCHANT_ID = 1
AND mpr.sku = '133';
It looks about right to me, what could be the problem here?
You must aggregate first in reviews and then join to catalog:
UPDATE catalog mpc
INNER JOIN (
SELECT merchant_id, sku, AVG(rating) avg_rating, COUNT(rating) count_rating
FROM reviews
WHERE merchant_id = 1 AND sku = '133'
GROUP BY merchant_id, sku
) mpr ON mpr.merchant_id = mpc.MERCHANT_ID and mpr.sku = mpc.ARTICLE_ID
SET mpc.RATING = mpr.avg_rating,
mpc.RATINGS = mpr.count_rating
I'm just 3 months of experience in MySQL. Here I'm trying to generate a report based on log and part table. When trying to join the "Part" table twice, the "Log" table Quantity gets doubled. Kindly let me know where I'm doing wrong.
Log Table
Part Table
Expected Report
Query Used
SELECT
report.*,
(SUM(report.quantity)) AS totalQuantity,
normalPart.price AS normalPrice,
premiumPart.price AS premiumPrice
FROM
log AS report
LEFT JOIN
(SELECT
*
FROM
part AS normalPart
WHERE
normalPart.type = 'normal'
GROUP BY normalPart.partNumber , normalPart.genId) AS normalPart ON report.partNumber = normalPart.partNumber
AND report.genId = normalPart.genId
AND normalPart.cat = report.fromCat
LEFT JOIN
(SELECT
*
FROM
part AS premiumPart
WHERE
premiumPart.type = 'premium'
GROUP BY premiumPart.partNumber , premiumPart.genId) AS premiumPart ON report.partNumber = premiumPart.partNumber
AND report.genId = premiumPart.genId
AND premiumPart.cat = report.toCat;
Query Result
This answers the original version of the question.
Aggregate before you join:
select l.*, p.normal_price, p.premium_price
from (select genid, partnumber, sum(quantity) as quantity
from log
group by genid, partnumber
) l left join
(select partnumber, genid,
max(case when type = 'normal' then price end) as normal_price,
max(case when type = 'premium' then price end) as premium_price
from part
group by partnumber, genid
) p
on p.partnumber = l.partnumber and p.genid = l.genid
I am trying to create a dynamic query that joins my tables and filters the filters selected. In my example, the products_bind_filters are the filter items that belong to each product.
I'm trying to find the products that have the following criteria as an example in one result:
Products that are Red, Green OR Blue
that are also available in Small or Medium
My query is:
SELECT *,
p.name as productName,
c.name as categoryName,
p.price as productPrice,
p.hookName as productHook,
c.hookName as categoryHook,
p.imageMain as productThumb
FROM products p
JOIN products_bind_category pbc ON pbc.productsId = p.productsId
JOIN category c ON pbc.categoryId = c.categoryId
JOIN products_bind_value pbv ON pbv.productsId = p.productsId
WHERE p.productsId != '0'
AND pbc.categoryId = '10'
AND (pbv.valueId = '54' ) AND (pbv.valueId = '167' OR pbv.valueId = '186' OR pbv.valueId = '175' )
GROUP BY p.productsId
ORDER BY p.Price ASC
However, it's not returning the correct results. There are products that match the criteria but it's not showing them.
Any ideas?
I did try use an IN query but it also didn't work.
You are working with a key/value table, which is always kind of hard.
This condition:
AND (pbv.valueId = '54')
AND (pbv.valueId = '167' OR pbv.valueId = '186' OR pbv.valueId = '175')
is never met, because no row in the table can have a value of 54 and not 54 at the same time.
One way to deal with key/values is aggregation:
select *
from products p
join products_bind_category pbc on pbc.productsid = p.productsid
join category c on pbc.categoryid = c.categoryid
where p.productsid in
(
select productsid
from products_bind_value
group by productsid
having sum(valueid = 54) > 0
and sum(valueid in (167, 196, 175)) > 0
)
order by p.productsid;
The SUM(<expression>) > 0) uses the fact that in MySQL true = 1, false = 0 by the way.
This is my query.
SELECT dr_trans_dtl.dr_ID, jo_trans_dtl.qty
FROM dr_trans_dtl
LEFT JOIN jo_trans_dtl ON dr_trans_dtl.jo_no = jo_trans_dtl.jo_no
WHERE dr_trans_dtl.dr_no = '3329' GROUP BY dr_trans_dtl.dr_ID
Here is the actual result:
What I wanted is the qty should be like this (500,40,1). Because that is the data in jo_trans_dtl.
It seems you need aggregate function as you used group by
SELECT dr_trans_dtl.dr_ID,sum(jo_trans_dtl.qty) as qty
FROM dr_trans_dtl
JOIN jo_trans_dtl ON dr_trans_dtl.jo_no = jo_trans_dtl.jo_no
WHERE dr_trans_dtl.dr_no = '3329'
GROUP BY dr_trans_dtl.dr_ID
I have the following query for a report all is working fine, but I need to add a variable in the report that totals up the number of records for each record returned based off the number of records in the "manheim_auction_listings" record. I feel like it needs to be inside a join but everywhere I would the "COUNT(*) AS num_of_runs" it seems to make the whole query only return a single line with the count the total number of records in the query rather than all the lines with a variable num_of_runs with the number of "manheim_auction_listings" records for each CAR record.
SELECT products.client_id,
clients.name AS client_name,
manheim_auction_lanes.lane_number,
manheim_auction_listings.sequence,
manheim_auction_listings.gross_sale_price,
products.asking_price, products.asking_price_condition,
manheim_auctions.auction_date,
manheim_auctions.auction_number,
product_purchases.total_spent,
product_purchases.purchase_price
FROM manheim_auction_listings
JOIN cars ON
cars.id = manheim_auction_listings.car_id
JOIN products ON
cars.product_id = products.id
JOIN product_purchases ON
current_product_purchase_id = product_purchases.id
JOIN manheim_auctions ON
manheim_auctions.id = manheim_auction_listings.manheim_auction_id
JOIN manheim_auction_lanes ON
manheim_auction_lanes.id = manheim_auction_listings.manheim_auction_lane_id
JOIN clients ON
clients.id = products.client_id
AND clients.id LIKE $P{LoggedInUserAttribute_ClientID}
WHERE
manheim_auctions.auction_number = $P{SaleNumber}
AND manheim_auctions.`year` = $P{SaleYear}
ORDER BY manheim_auction_lanes.lane_number DESC,
manheim_auction_listings.sequence DESC
Please try the following...
SELECT products.client_id,
clients.name AS client_name,
manheim_auction_lanes.lane_number,
manheim_auction_listings.sequence,
manheim_auction_listings.gross_sale_price,
num_of_runs,
products.asking_price, products.asking_price_condition,
manheim_auctions.auction_date,
manheim_auctions.auction_number,
product_purchases.total_spent,
product_purchases.purchase_price
FROM ( SELECT manheim_auction_id AS manheim_auction_id,
COUNT( manheim_auction_id ) AS num_of_runs
FROM manheim_auction_listings
GROUP BY manheim_auction_id
) AS num_of_runs_finder
JOIN manheim_auction_listings ON manheim_auction_listings.manheim_auction_id = num_of_runs.manheim_auction_id
JOIN cars ON cars.id = manheim_auction_listings.car_id
JOIN products ON cars.product_id = products.id
JOIN product_purchases ON current_product_purchase_id = product_purchases.id
JOIN manheim_auctions ON manheim_auctions.id = manheim_auction_listings.manheim_auction_id
JOIN manheim_auction_lanes ON manheim_auction_lanes.id = manheim_auction_listings.manheim_auction_lane_id
JOIN clients ON clients.id = products.client_id
AND clients.id LIKE $P{LoggedInUserAttribute_ClientID}
WHERE manheim_auctions.auction_number = $P{SaleNumber}
AND manheim_auctions.`year` = $P{SaleYear}
ORDER BY manheim_auction_lanes.lane_number DESC,
manheim_auction_listings.sequence DESC
This works by joining your other tables to one that calculates the number of listings associated with each manheim_auction_id, effectively appending a manheim_auction_id's count to each row where that manheim_auction_id occurs.
If num_of_runs is calculated on some other criteria, then please advsie me accordingly.
If you have any questions or comments, then please feel free to post a Comment accordingly.