I am trying to only get rows from video_index that belongs to a specific category from category_video_rel and order the result by COUNT of view count. This is the query I'm using:
SELECT
COUNT(DISTINCT view_count.id) AS count,
view_count.remove,
view_count.video_id,
video_index.id AS video_id,
video_index.active,
video_index.remove,
video_index.title AS title,
video_index.date_published AS date_published,
category_video_rel.active,
category_video_rel.remove,
category_video_rel.video_id AS cv_video_id,
category_video_rel.category_id AS category_id
FROM
view_count JOIN video_index
ON view_count.video_id = video_index.id,
category_video_rel JOIN video_index AS v
ON category_video_rel.video_id = v.id
WHERE
view_count.remove = '0' AND
video_index.active = '1' AND
video_index.remove = '0' AND
video_index.date_published <= '$current_time' AND
category_video_rel.category_id = '$category_id' AND
category_video_rel.active = '1' AND
category_video_rel.remove = '0'
GROUP BY
video_index.id
ORDER BY
count DESC
The problem is it outputs all the rows from video_index with a view count higher than 0 regardless of the category. Basically, it's ignoring "category_video_rel.category_id = '$category_id'" in the WHERE condition.
I have no idea what I'm doing wrong, please help.
Your FROM clause is mixing old style joins and new style joins
Instead try:
FROM
view_count JOIN video_index
ON view_count.video_id = video_index.id
JOIN category_video_rel
ON category_video_rel.video_id = video_index.id
Related
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.
I have two tables:-
gallery
gallery_favorite
The user_id in gallery table means the user who posted the item. The user_id in gallery_favorite means the user who added the item in his favorite list. If favorite = 0, then it means the user had initially added the item in favorite list but later removed it.
Now, I want to fetch all the gallery items along with its favorite status. Here is my query:-
Select distinct `gallery`.`id`, `gallery`.`caption`, `gallery`.`type`,
`gallery`.`video`, `gallery`.`image`, `gallery`.`type`,
`gallery`.`created_date`, `gallery`.`modified_date`,
`gallery_favorite`.`favorite`, `gallery`.`user_id`
from `gallery`
left join `gallery_favorite` on `gallery_favorite`.`gallery_id` = `gallery`.`id`
where
(`gallery`.`type` = 'i'
and `gallery`.`status` = 1
and `gallery`.`deleted` = 0)
and
((`gallery`.`user_id` != 11 and `gallery`.`private` = 0)
or `gallery`.`user_id` = 11)
limit 20 offset 0
But a syou can see, I am getting duplicate records depending upon the number of rows wrt to a gallery item in the gallery favorite table. How can I modify the query to get only one record (along with my own favorite status)?
I guess you are getting duplicate records because you have not joined both the table on user_id -
Try below query -
Select distinct `gallery`.`id`, `gallery`.`caption`, `gallery`.`type`,
`gallery`.`video`, `gallery`.`image`, `gallery`.`type`,
`gallery`.`created_date`, `gallery`.`modified_date`,
`gallery_favorite`.`favorite`, `gallery`.`user_id`
from `gallery`
left join `gallery_favorite` on `gallery_favorite`.`gallery_id` = `gallery`.`id`
and `gallery_favorite`.`user_id` = `gallery`.`user_id`
where
(`gallery`.`type` = 'i'
and `gallery`.`status` = 1
and `gallery`.`deleted` = 0)
and
((`gallery`.`user_id` != 11 and `gallery`.`private` = 0)
or `gallery`.`user_id` = 11)
limit 20 offset 0
Assuming the gallery as many favorites from different users. It makes no sense to display exclusively a hit favorite to a user and gallery alone. Counting them makes sense.
Select `gallery`.`id`, `gallery`.`caption`, `gallery`.`type`,
`gallery`.`video`, `gallery`.`image`, `gallery`.`type`,
`gallery`.`created_date`, `gallery`.`modified_date`,
sum(gallery_favorite`.`favorite`) as total_favorites -- count them group function aggregate
from `gallery`
left join `gallery_favorite` on `gallery_favorite`.`gallery_id` = `gallery`.`id`
where
(`gallery`.`type` = 'i'
and `gallery`.`status` = 1
and `gallery`.`deleted` = 0)
and
((`gallery`.`user_id` != 11 and `gallery`.`private` = 0)
or `gallery`.`user_id` = 11)
and gallery_favorite`.`favorite` = 1 -- count only the favorites
GROUP BY `gallery`.`id` -- GROUP CLAUSE
This is how a join works. You get all rows matching the condition. You can either group the result by the fields in the left table (thus eliminating duplicates in the output) or join with a table that has one entry per gallery item -- this requires joining with a (SELECT ... FROM gallery_favorite GROUP BY gallery_id)
The original query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop.price_type_code,
fop.price_status_code,
fop.offering_id,
(SELECT fop1.price_amount from facility_offering_price fop1
WHERE fop.offering_id = fop1.Offering_Id
AND fop1.price_type_code = 5
AND fop1.price_status_code = 3
) as 'priceAmount'
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It produces a result of one entry.
The result query:
SELECT o.offering_number,
o.english_description,
o.french_description,
fop.price_amount,
fop2.price_amount,
fop.price_type_code,
fop.offering_id,
fop2.offering_id
from facility_offering_price fop
join offering o on fop.offering_id = o.offering_id
inner join
(select
fop1.offering_id,
fop1.price_amount
from facility_offering_price fop1
WHERE fop1.price_type_code = 5
AND fop1.price_status_code = 3
) fop2 on fop.offering_id = fop2.offering_id
WHERE fop.price_start_date = '15-10-28'
AND fop.price_status_code IN (1,2)
/*AND (price_status_code IS NULL)*/
AND fop.price_type_code = 5
/*AND (o.offering_number IS NULL)*/
ORDER BY o.offering_number ASC, fop.price_sequence_number ASC;
It's result set is empty. However, an entry is found if I ask for fop1.price_status_code = 1.
Unable to wrap my head around this one I would appreciate your help.
Try using LEFT JOIN instead. The conversion from SELECT a, subquery AS val FROM ... to a join is more accurately reflected that way. The original query would return rows with NULL val when the subquery has no results; your version ends up omitting such rows completely.
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.
This is my query.
select sp.name, spi.sku, sum(spi.price), count(sp.name), spi.in_stock, spi.price, sp.is_published, spi.is_reorderable
from shop_product_category spc
inner join shop_product_category_xref spcx
on spc.shop_product_category_id = spcx.shop_product_category_id
inner join shop_product sp
on sp.shop_product_id = spcx.shop_product_id
inner join shop_product_item spi
on spi.shop_product_id = sp.shop_product_id
inner join shop_order_item soi
on spi.shop_product_item_id = soi.shop_product_item_id
where (spc.shop_product_category_id in (1316))
and sp.is_published = 1
group by sp.name
order by count(sp.name) desc
It returns everything just fine EXCEPT I want it to return lines where sp.is_published = 1 Hence the where clause. Yet to get the desired output, I have to change the current where clause to
sp.is_published <> 1
So the questions is this, why does <> 1 return rows with ones, and =1 return rows with zeros. Thanks
If sp.is_published = 1 is a string, you'll need to put it in ticks IE sp.is_published = '1'