Mysql error not following where condition - mysql

Why is this sql giving tables with minimum field having null. Also when A has no data between the given date ranges, it is providing the table with all rooms having minimum as null
SELECT `rooms`.*,A.`minimum`
FROM (
SELECT `room_id`, min(`available_rooms`) AS `minimum`
FROM `room_bookings`
WHERE `date` BETWEEN '2014-02-01' and '2014-02-10'
GROUP BY `room_id`) as A
INNER JOIN `rooms` on `rooms`.`room_id`=A.`room_id`
WHERE `rooms`.`location`='kathmandu'
AND `rooms`.`status`=1
AND A.`minimum`!=NULL

SELECT `rooms`.*,A.`minimum`
FROM (
SELECT `room_id`, min(`available_rooms`) AS `minimum`
FROM `room_bookings`
WHERE `date` BETWEEN '2014-02-01' and '2014-02-10'
GROUP BY `room_id` having minimum > 0) as A
INNER JOIN `rooms` on `rooms`.`room_id`=A.`room_id`
WHERE `rooms`.`location`='kathmandu'
AND `rooms`.`status`=1

SELECT `rooms`.*,A.`minimum`
FROM (
SELECT `room_id`, min(`available_rooms`) AS `minimum`
FROM `room_bookings`
WHERE `date` BETWEEN '2014-02-01' and '2014-02-10'
GROUP BY `room_id`) as A
INNER JOIN `rooms` on `rooms`.`room_id`=A.`room_id`
WHERE `rooms`.`location`='kathmandu'
AND `rooms`.`status`=1
AND A.`minimum` is not NULL
This would be the correct syntax ( change != to is not )

Try this:
SELECT r.*, MIN(rb.available_rooms) minimum
FROM rooms r
INNER JOIN room_bookings rb ON r.room_id = rb.room_id AND rb.date BETWEEN '2014-02-01' AND '2014-02-10'
WHERE r.location = 'kathmandu' AND r.status = 1
GROUP BY r.room_id HAVING minimum IS NOT NULL

try this with IS NOT NULL
SELECT `rooms`.*,A.`minimum`
FROM (
SELECT `room_id`, min(`available_rooms`) AS `minimum`
FROM `room_bookings`
WHERE `date` BETWEEN '2014-02-01' and '2014-02-10'
GROUP BY `room_id`) as A
INNER JOIN `rooms` on `rooms`.`room_id`=A.`room_id`
WHERE `rooms`.`location`='kathmandu'
AND `rooms`.`status`=1
AND A.`minimum` IS NOT NULL

Related

Mysql query dosen't provide the result needed

I've been trying to figure this one out for days but can't come up with a solution.
Here are the table schemes.
This is my current query.
SELECT DISTINCT `address`, `order`.`id`
FROM `order`, `ordered_articles`
WHERE `order`.`id` = `f_order_id`
AND `Status` > 1
AND `Status` <4;
The problem is that the query returns as long as there is one article with status bigger than 1. I need a query where all the articles of that order have a status bigger than 1.
You can do it with NOT EXISTS:
SELECT o.`address`, o.`id`
FROM `order` o
WHERE NOT EXISTS (
SELECT 1 FROM `ordered_articles`
WHERE `f_order_id` = o.`id`
AND (`Status` <= 1 OR `Status` >= 4 )
);
or:
SELECT o.`address`, o.`id`
FROM `order` o INNER JOIN `ordered_articles` i
ON i.`f_order_id` = o.`id`
GROUP BY o.`address`, o.`id`
HAVING SUM(`Status` <= 1 OR `Status` >= 4) = 0;

MySQL where condition based on select query

I am having the following query to fetch the data from the table.
SELECT rental_plans.*,
( ( inventory.total_inventory
+ vehicles.tmp_qty ) - Ifnull(reservation.total_reserved, 0) ) AS
vehicle_inventory
FROM `rental_plans`
INNER JOIN `vehicles`
ON `vehicles`.`id` = `rental_plans`.`vehicle_id`
LEFT JOIN (SELECT Count(*) AS total_inventory,
vehicle_id
FROM vehicle_inventories
GROUP BY vehicle_id) AS inventory
ON `inventory`.`vehicle_id` = `vehicles`.`id`
LEFT JOIN (SELECT vehicle_id,
Sum(qty) AS total_reserved
FROM `reservations`
WHERE ( '2018-12-18' BETWEEN pickup_date AND drop_date )
OR ( '2018-12-28' BETWEEN pickup_date AND drop_date )
AND `status` NOT IN ( 'RETURNED' )
GROUP BY `vehicle_id`) AS `reservation`
ON `rental_plans`.`vehicle_id` = `reservation`.`vehicle_id`
WHERE `rental_plans`.`id` > 0
AND `rental_plans`.`pickup` = '1'
AND `rental_plans`.`drop` = '10'
ORDER BY `rental_plans`.`price` ASC
But I want to handle where condition based on vehicle_inventory.
I tried with ... AND vehicle_inventory > 16 order by `rental_plans`.`price` ASC but this generates the error that column not found in the table
The reason is that vehicle_inventory is an alias and it is resolved after WHERE clause. You can read about that here. You can do something like:
SELECT *
FROM (SELECT rental_plans.*,
( ( inventory.total_inventory
+ vehicles.tmp_qty ) - Ifnull(reservation.total_reserved, 0)
) AS
vehicle_inventory
FROM `rental_plans`
INNER JOIN `vehicles`
ON `vehicles`.`id` = `rental_plans`.`vehicle_id`
LEFT JOIN (SELECT Count(*) AS total_inventory,
vehicle_id
FROM vehicle_inventories
GROUP BY vehicle_id) AS inventory
ON `inventory`.`vehicle_id` = `vehicles`.`id`
LEFT JOIN (SELECT vehicle_id,
Sum(qty) AS total_reserved
FROM `reservations`
WHERE ( '2018-12-18' BETWEEN
pickup_date AND drop_date )
OR ( '2018-12-28' BETWEEN
pickup_date AND drop_date )
AND `status` NOT IN ( 'RETURNED' )
GROUP BY `vehicle_id`) AS `reservation`
ON `rental_plans`.`vehicle_id` =
`reservation`.`vehicle_id`
WHERE `rental_plans`.`id` > 0
AND `rental_plans`.`pickup` = '1'
AND `rental_plans`.`drop` = '10')a
WHERE a.rental_plans > 16
ORDER BY `price` ASC
or
SELECT rental_plans.*,
( (inventory.total_inventory + vehicles.tmp_qty) - Ifnull(reservation.total_reserved, 0) ) AS vehicle_inventory
FROM `rental_plans`
INNER JOIN `vehicles`
ON `vehicles`.`id` = `rental_plans`.`vehicle_id`
LEFT JOIN
(
SELECT Count(*) AS total_inventory,
vehicle_id
FROM vehicle_inventories
GROUP BY vehicle_id) AS inventory
ON `inventory`.`vehicle_id` = `vehicles`.`id`
LEFT JOIN
(
SELECT vehicle_id,
Sum(qty) AS total_reserved
FROM `reservations`
WHERE (
'2018-12-18' BETWEEN pickup_date AND drop_date)
OR (
'2018-12-28' BETWEEN pickup_date AND drop_date)
AND `status` NOT IN ('RETURNED')
GROUP BY `vehicle_id`) AS `reservation`
ON `rental_plans`.`vehicle_id` = `reservation`.`vehicle_id`
WHERE `rental_plans`.`id` > 0
AND `rental_plans`.`pickup` = '1'
AND `rental_plans`.`drop` = '10'
where (
inventory.total_inventory + vehicles.tmp_qty) - ifnull(reservation.total_reserved, 0) > 16
ORDER BY `rental_plans`.`price` ASC

Error Number: 1241 Operand should contain 1 column(s)

SELECT *
FROM `tbl_equipments` as `E`
JOIN `tbl_equipment_category` as `C` ON `C`.`equipment_category_id`=`E`.`equipment_category_id`
JOIN `tbl_suppliers` as `S` ON `S`.`supplier_id`=`E`.`supplier_id`
JOIN `tbl_site_users` as `U` ON `U`.`user_id`=`E`.`created_by`
JOIN `tbl_currency` as `R` ON `R`.`currency_id`=`E`.`equipment_currency_id`
WHERE `E`.`site_id` = '3'
AND (SELECT *
FROM `tbl_user_delegates` as `D`
LEFT JOIN `tbl_equipments` as `E` ON `E`.`approve_by`=`D`.`delegate_from_user`
WHERE `D`.`delegate_from_date` <= '2016-10-27'
AND `D`.`delegate_to_date` >= '2016-10-27' AND `D`.`delegate_to_user` = '5'
ORDER BY `E`.`equipment_id` DESC)
AND (`E`.`approve_flg` =0 and `E`.`rejection_flg` =0) AND `E`.`approve_by` = '5'
Your AND ( subselect ) return * this is wrong
you should use exists
SELECT *
FROM `tbl_equipments` as `E`
JOIN `tbl_equipment_category` as `C` ON `C`.`equipment_category_id`=`E`.`equipment_category_id`
JOIN `tbl_suppliers` as `S` ON `S`.`supplier_id`=`E`.`supplier_id`
JOIN `tbl_site_users` as `U` ON `U`.`user_id`=`E`.`created_by`
JOIN `tbl_currency` as `R` ON `R`.`currency_id`=`E`.`equipment_currency_id`
WHERE `E`.`site_id` = '3'
AND EXISTS (SELECT *
FROM `tbl_user_delegates` as `D`
LEFT JOIN `tbl_equipments` as `E` ON `E`.`approve_by`=`D`.`delegate_from_user`
WHERE `D`.`delegate_from_date` <= '2016-10-27'
AND `D`.`delegate_to_date` >= '2016-10-27' AND `D`.`delegate_to_user` = '5'
ORDER BY `E`.`equipment_id` DESC)
AND (`E`.`approve_flg` =0 and `E`.`rejection_flg` =0) AND `E`.`approve_by` = '5'
adn Just a tips order by in select select is unuseful

MySQL "Every derived table must have its own alias"

I am a little confused by this strange MySQL behaviour. I am receiving the dreaded Every derived table must have its own alias error.
Usually, I can circumvent this by adding an AS clause to the primary SELECT statement, however it does not see to work with the following example:
SELECT SUM (`a`.`total`) AS `total` FROM (
SELECT COUNT(DISTINCT(`item_sales`.`id`)) AS `total`,
(SELECT COUNT(DISTINCT(`sale_item`)) AS `offers` FROM `item_sales_bids` WHERE `user_id` = 2) AS `offers`
FROM `item_sales`
INNER JOIN `item_sales_bids` ON `item_sales`.`id` = `item_sales_bids`.`sale_item`
WHERE `item_sales`.`buyer` != 2
AND `item_sales`.`sold` = 1
GROUP BY `item_sales`.`id`
HAVING `offers` > 0
) UNION (
SELECT COUNT(*) AS `total`,
`item_sales`.`reserve`,
(SELECT COUNT(*) FROM `item_sales_bids` WHERE `user_id` = 2) AS `bids`,
(SELECT MAX(`max_bid`) AS `max` FROM `item_sales_bids` WHERE `user_id` = 2) AS `maxBid`,
SUM((`item_sales`.`list_date` + (`item_sales`.duration * 86400)) - UNIX_TIMESTAMP()) AS `endTime`
FROM `item_sales`
INNER JOIN `item_sales_bids` ON `item_sales_bids`.`sale_item` = `item_sales`.`id`
GROUP BY `item_sales`.`id`
HAVING `endTime` < 0
AND `maxBid` < `item_sales`.`reserve`
)
) `a`
Can anyone point out what I am missing? Please note that adding an alias to the joins results in the same error.
You should put an UNION keyword inside the subquery as below
SELECT SUM (`a`.`total`) AS `total`
FROM (
SELECT COUNT(DISTINCT(`item_sales`.`id`)) AS `total`,
(SELECT COUNT(DISTINCT(`sale_item`)) AS `offers` FROM `item_sales_bids` WHERE `user_id` = 2) AS `offers`
FROM `item_sales`
INNER JOIN `item_sales_bids` ON `item_sales`.`id` = `item_sales_bids`.`sale_item`
WHERE `item_sales`.`buyer` != 2
AND `item_sales`.`sold` = 1
GROUP BY `item_sales`.`id`
HAVING `offers` > 0
UNION
SELECT COUNT(*) AS `total`,
`item_sales`.`reserve`,
(SELECT COUNT(*) FROM `item_sales_bids` WHERE `user_id` = 2) AS `bids`,
(SELECT MAX(`max_bid`) AS `max` FROM `item_sales_bids` WHERE `user_id` = 2) AS `maxBid`,
SUM((`item_sales`.`list_date` + (`item_sales`.duration * 86400)) - UNIX_TIMESTAMP()) AS `endTime`
FROM `item_sales`
INNER JOIN `item_sales_bids` ON `item_sales_bids`.`sale_item` = `item_sales`.`id`
GROUP BY `item_sales`.`id`
HAVING `endTime` < 0
AND `maxBid` < `item_sales`.`reserve`
) `a`
you can include UNION inside the subquery,
SELECT SUM (`a`.`total`) AS `total`
FROM
(
--- your first query
UNION
--- your second query
) a

Merge two similar aggregate functions in select statement

Here's a SQL statement:
SELECT DISTINCT `class`, `student_id` , `student_name`,
(
SELECT SUM( `credits` )
FROM `stumgr_scores` B
JOIN `stumgr_courses` USING ( `course_id` )
WHERE `year` =2012 AND A.`student_id` = B.`student_id`
) AS `total_credits`,
(
SELECT SUM( `credits` * `final_score` )
FROM `stumgr_scores` C
JOIN `stumgr_courses` USING ( `course_id` )
WHERE `year` =2012 AND A.`student_id` = C.`student_id`
) AS `total_scores`
FROM `stumgr_scores` A
NATURAL JOIN `stumgr_students`
WHERE `year` =2012 AND `grade` =2011
You may discover that these two select statement which use aggregate functions are similar. So, I want to merge them into one as following:
SELECT DISTINCT `class`, `student_id` , `student_name`,
(
SELECT
SUM( `credits` ) AS `total_credits`,
SUM( `credits` * `final_score` ) AS `total_scores`
FROM `stumgr_scores` B
JOIN `stumgr_courses` USING ( `course_id` )
WHERE `year` =2012 AND A.`student_id` = B.`student_id`
) AS `something`
FROM `stumgr_scores` A
NATURAL JOIN `stumgr_students`
WHERE `year` =2012 AND `grade` =2011
Of course, the SQL statement above doesn't work and I don't know what to do.
Besides, the query is very slow because of large data, do you have any suggestions? Thanks a lot.
I have had to guess at your table structure slightly, but you should be able to simplify this query massively by using JOINs rather than correlated subqueries:
SELECT st.student_id,
st.student_name,
c.class,
SUM(sc.credits) AS total_credits,
SUM(sc.credits * sc.final_score) AS total_scores
FROM stumgr_students st
INNER JOIN stumgr_scores sc
ON sc.student_id = st.student_id
INNER JOIN stumgr_courses c
ON c.course_id = st.course_id
GROUP BY st.student_id, st.student_name, c.class;