Get available apartments - php

With this query i will find all apartments that are available.
All the available apartments have no booking id.
What i want: When it has a booking id and the status is cancelled I also want the apartment to show up, but i don't know how to…
SELECT a.id, a.num_persons, a.rating, a.lat, a.lng, a.street, a.number
,c.title, c.introduction, c.text, c.area, c.long_term_rental, c.beds
, c.features ,c.services_and_equipment, c.terms_and_conditions
, m.url
FROM appartments AS a
INNER JOIN appartments_content AS c on c.parent_id = a.id
INNER JOIN meta AS m on m.id = c.meta_id
LEFT JOIN appartments_bookings AS b
ON (b.appartment_id = a.id
AND NOT ((? > b.departure) OR (? < b.arrival)))
-- this ? = arrival that ? = departure
WHERE b.id IS NULL
AND c.language = ?
AND a.hidden = ?
AND a.publish_on <= ?
AND a.city_id = ?
AND a.num_persons >= ?
ORDER BY a.num_persons ASC, a.publish_on DESC
LIMIT ? OFFSET ?'
I added this:
AND b.status != ? OR NOT ((? >= b.departure) OR (? < b.arrival))) WHERE b.order_id IS NULL
But this doesn't work, i get nog results.

Don't know mySQL syntax but change your WHERE to clause to something like...
WHERE (b.id IS NULL OR (b.id IS NOT NULL AND b.status = 'cancelled'))
AND c.language = etc etc

Related

UNION ALL use with INNER JOIN

I am trying to join 3 tables with UNION ALL. I tried the following code. and giving this error of Invalid parameter number: number of bound variables does not match number of tokens.
$codeArray = explode(',', $code);
$inQuery = implode(',', array_fill(0, count($codeArray), '?'));
$full_dt = date('Y-m-d H:i:s');
$query = "SELECT * FROM
(
SELECT
a.*
FROM pat_info a
INNER JOIN
pat_medication b
ON a.id = b.pat_id
WHERE
a.status != 2 AND b.status != 2
AND '$full_dt' BETWEEN b.start_date AND b.end_date
AND a.location_code IN ($inQuery)
AND b.stock_status != '2'
AND (b.total_qty - (b.given + b.not_taken)) < 12
UNION ALL
SELECT
a.*
FROM pat_info a
INNER JOIN
prn_medication b
ON a.id = b.pat_id
WHERE
a.status != 2 AND b.status != 2
AND '$full_dt' BETWEEN b.start_date AND b.end_date
AND a.location_code IN ($inQuery)
AND b.stock_status != '2'
AND (b.total_qty - (b.given + b.not_taken)) < 12
) x
GROUP BY a.id ORDER BY a.id DESC";
$statement = $con->prepare($query);
$statement->execute($codeArray);
As you have the in clause twice in your code, you need to bind the values twice.
A simple way to do this would be to duplicate the data prior to the execute()...
$codeArray = array_merge($codeArray, $codeArray);
You also need to change
GROUP BY a.id ORDER BY a.id DESC
to
GROUP BY x.id ORDER BY x.id DESC
as the a alias is in the sub-select and not the overall SELECT.

Select INNER JOIN mysql DataBase

I want to select database with condition but not working.
I have this query :
SELECT c.*
,s.*
,f.*
,count(c.id) as instock_count
,totals.orders_total
,GROUP_CONCAT(c.sku SEPARATOR '<br/>') AS sku
FROM produse_com c
INNER JOIN (SELECT * , SUM(stoc) as stoc_sum
FROM stocuri_mentor
GROUP BY sku ) s
ON c.sku = s.sku
INNER JOIN (SELECT count(id) as orders_total, id_comanda
FROM produse_com
WHERE NOT ridicat = 'Da'
GROUP BY id_comanda ) totals
ON totals.id_comanda = c.id_comanda
INNER JOIN (SELECT data_add, status, id_comanda
FROM comenzi
WHERE NOT (status = 'Impachetat' OR status = 'Stornat' OR status = 'Anulat')
) f
ON f.id_comanda = c.id_comanda
WHERE stoc_sum >= c.qty
GROUP BY c.id_comanda
HAVING instock_count = orders_total
The issue is I have a condition WHERE NOT ridicat = 'Da'
But the result contain all result with ridicat = 'Da'
EDIT :
If I remove this query INNER JOIN (SELECT * ,SUM(stoc) as stoc_sum FROM stocuri_mentor GROUP BY sku ) s ON c.nume_produs = s.sku AND WHERE stoc_sum >= c.qty the result is OK
EDIT 2 : SOLUTION = add 1 more condition WHERE stoc_sum >= c.qty AND ridicat <> 'Da'
You can try this query.
SELECT count(id) as orders_total, id_comanda, ridicat
FROM produse_com
WHERE ridicat != 'Da'
GROUP BY id_comanda;

SELECT product variants SQL

This is my query without variant options
SELECT p.*, pd.`name` AS `product_name`
FROM `product` AS `p`
LEFT JOIN `product_description` AS `pd` ON p.`id` = pd.`product_id`
LEFT JOIN `product_to_variant` AS `pv` ON p.`id` = pv.`product_id`
WHERE p.`status` = 0
GROUP BY p.`id`
ORDER BY p.`id` DESC;
SQLFiddle: http://sqlfiddle.com/#!9/8955b/5
and the follwing query has variant options but it doesn't work
SELECT p.*, pd.`name` AS `product_name`
FROM `product` AS `p`
LEFT JOIN `product_description` AS `pd` ON p.`id` = pd.`product_id`
LEFT JOIN `product_to_variant` AS `pv` ON p.`id` = pv.`product_id`
WHERE p.`status` = 0
AND (pv.`feature_id` = 2 AND pv.`variant_id` = 6)
AND (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
GROUP BY p.`id`
ORDER BY p.`id` DESC;
and I also trying to query but there is no output
SELECT pv.* FROM `product_to_variant` AS `pv`
WHERE (pv.`feature_id` = 2 AND pv.`variant_id` = 2)
AND (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
Do you have any other idea how to receive the products: 14, 15 by specific variant_id 6 AND 11 http://prntscr.com/ect2oh
Here is one method to do what you want:
SELECT p.*, pd.name AS product_name
FROM product p LEFT JOIN
product_description pd
ON p.id = pd.product_id JOIN
product_to_variant pv
ON p.id = pv.product_id
WHERE p.status = 0 AND
((pv.feature_id = 2 AND pv.variant_id = 6) OR
(pv.feature_id = 3 AND pv.variant_id = 11)
)
GROUP BY p.id
HAVING COUNT(DISTINCT feature_id) = 2
ORDER BY p.id DESC;
Notes:
No row can meet your original conditions. Because a column cannot have two values at the same time. Hence the OR rather than AND.
The HAVING clause checks that both values match.
There is no need for a LEFT JOIN to pv, because you are checking values from that table in the WHERE clause -- there have to be matches.
The LEFT JOIN to pa is probably also unnecessary.
Using backticks everywhere just makes the query harder to write and to read.
Maybe like this:
SELECT pv.* FROM `product_to_variant` AS `pv`
WHERE (pv.`feature_id` = 2 AND pv.`variant_id` = 2)
OR (pv.`feature_id` = 3 AND pv.`variant_id` = 11)
Instead of AND, which says, you need both feature_id and variant_id in the results, use OR because it takes both.

simplify this SQL request

I have this sql request :
SELECT pl.*, l.loyer, l.charges, l.locataire_id, laire.nom, laire.prenom,
l.chambre_id, c.numero, c.etage, c.maison_id, m.titre_crm
FROM
(
SELECT spl.id, spl.location_id, spl.mois, spl.annee, spl.loyer_paye
from locations sl
LEFT JOIN
(
SELECT * FROM paiement_loyer
union
SELECT 9999, usl.id, (MONTH(NOW())-1), YEAR(NOW()), 0
FROM locations usl
WHERE usl.id not in (SELECT location_id FROM paiement_loyer) ||
(select count(*) FROM paiement_loyer
WHERE location_id = usl.id AND annee = YEAR(NOW())
AND mois=(MONTH(NOW())-1) ) = 0
) spl ON sl.id = spl.location_id
where sl.date_debut <= CURDATE() && CURDATE() <= sl.date_fin
) pl
JOIN locations l ON pl.location_id = l.id
JOIN locataires laire ON l.locataire_id = laire.id
JOIN chambres c ON l.chambre_id = c.id
JOIN maisons m ON c.maison_id = m.id
ORDER BY trim(upper(m.titre_crm)), c.numero, annee, mois
I would like to simplify it, do you have any idea please ?
An attempt at cleaning it up. Note that I think the first LEFT OUTER JOIN could probably be swapped to an INNER JOIN.
I have swapped the 2nd UNIONed query to 2 queries, and for those I have changed them to use LEFT OUTER JOINs which then check that there isn't a match
SELECT pl.id, pl.location_id, pl.mois, pl.annee, pl.loyer_paye,
l.loyer, l.charges, l.locataire_id, laire.nom, laire.prenom,
l.chambre_id, c.numero, c.etage, c.maison_id, m.titre_crm
FROM
(
SELECT spl.id, spl.location_id, spl.mois, spl.annee, spl.loyer_paye
FROM locations sl
LEFT OUTER JOIN
(
SELECT id, location_id, mois, annee, loyer_paye
FROM paiement_loyer
UNION
SELECT 9999, usl.id, (MONTH(NOW())-1), YEAR(NOW()), 0
FROM locations usl
LEFT OUTER JOIN paiement_loyer pl1
ON usl.id = pl1.location_id
WHERE pl1.location_id IS NULL
SELECT 9999, usl.id, (MONTH(NOW())-1), YEAR(NOW()), 0
FROM locations usl
LEFT OUTER JOIN paiement_loyer pl2
ON usl.id = pl1.location_id
AND pl2.annee = YEAR(NOW())
AND pl2.mois=(MONTH(NOW())-1)
WHERE pl2.location_id IS NULL
) spl ON sl.id = spl.location_id
WHERE CURDATE() BETWEEN sl.date_debut AND sl.date_fin
) pl
JOIN locations l ON pl.location_id = l.id
JOIN locataires laire ON l.locataire_id = laire.id
JOIN chambres c ON l.chambre_id = c.id
JOIN maisons m ON c.maison_id = m.id
ORDER BY TRIM(UPPER(m.titre_crm)), c.numero, pl.annee, pl.mois

mysql query not fetching data from where condition

I have written a MySQL query ?I want to fetch data t.taskid = b.id OR t.taskid = '0' AND t.subtaskid = j.id OR t.subtaskid = '0' from this but where condition is not working for this
SELECT t.id as id
, t.taskid
, t.subtaskid
, p.PNAME AS projectname
, t.date AS DATE
, b.Summary AS tasks
, j.SUMMARY AS subtasks
, t.mon AS time1
, t.tue AS time2
, t.wed AS time3
, t.thu AS time4
, t.fri AS time5
, t.sat AS time6
, t.sun AS time7
FROM bt_createissue b
, bt_createissue j
, timesheet t
LEFT
JOIN bt_project p
ON t.projectid = p.pkey
WHERE t.taskid = b.id
OR t.taskid = 0
AND t.subtaskid = j.id
OR t.subtaskid = 0
AND t.date >= '2015-03-09'
AND t.date <= '2015-03-30'
AND t.username = '$username'
If t.taskid = b.id
t.subtaskid = j.id are to be joins then check whether you can modify
WHERE t.taskid = b.id OR t.taskid = '0'
AND t.subtaskid = j.id OR t.subtaskid = '0'
the above lines with proper joins.
Because using join conditions in where clause can create cross join instead of intended one.
If it do not work
Try with using having clause instead of where clause and don't forget to use group by

Categories