MySQL sql ignoring WHERE condition - mysql

I have the following problem - I am coding an e-commerce website, that has promotions for a certain period of time. When time elapses promotion changes its corresponding database active value to 0. When I check for promotions the first condition is that active=1, but at some cases MySQL is ignoring it.
Here is an example of my most recent problem:
$productPromotion = $db->getResults('*', TABLE_PROMO, "active = '1'
AND (discount_subject = 'all_orders'
OR discount_subject_product = ".$values['product']['id'].")
OR (discount_subject = 'category'
AND discount_subject_category = ".$categoryId[0] . ") ORDER BY id ASC");
$db->getResult is a custom function that takes 3 parameters - What, Table and Where.
The problem is that it is returning promotions that are already expired and have active=0. Where is the problem with my sql?

You have to add brackets arround or
$productPromotion = $db->getResults('*', TABLE_PROMO, "active = '1'
AND
((discount_subject = 'all_orders' OR discount_subject_product = ".$values['product']['id'].")
OR (discount_subject = 'category' AND discount_subject_category = ".$categoryId[0] . ")) ORDER BY id ASC");
Also learn about prepared Statements to prevent SQL-injection

Related

Update a column value if two specific conditions are met in MySQL

I'm very much a newbie to programming.
I am trying to update my table column labelled 'bonus' with a new value of 505.99 if two conditions are met: if the givenname is Mary and their bonus is currently 155.99, or if their occupation is a Model and their bonus is also currently 155.99. 7 rows should be updated but only 1 is being updated.
The query looks like it should work to me so wondering what I am missing?
Looking for any pointers!
Thanks in advance
UPDATE customers
SET bonus = 505.99
WHERE occupation = 'Model' AND bonus = 155.99
OR givenname = 'Mary' AND bonus = 155.99;
Can you try to use parentheses like these?
UPDATE customers
SET bonus = 505.99
WHERE
(occupation = 'Model' AND bonus = 155.99)
OR
(givenname = 'Mary' AND bonus = 155.99);
You should use AND and OR conditions properly when you use those simultaneously.
Let us build your query :
As we know we are going to set value wherever following holds true.
Either occupation = 'Model' OR givenname = 'Mary'
This should be written with OR together
bonus = 155.99 : This we can add separately using AND in the select query.
So; the correct condition to use is (occupation = 'Model' OR givenname = 'Mary') and bonus = 155.99;
We can re-write the above query as :
UPDATE customers
SET bonus = 505.99
WHERE bonus = 155.99
AND (occupation = 'Model' OR givenname = 'Mary');
You can find more good examples here :

Select SQL statement from multiple database

My question has 2 parts, and i am unsure if it is my query which is causing the error or data adapter.
Part 1. I have a mySQL query which works fine on SQLyog, the query involves selection from tables existing in different databases. And both databases has been set to have the same accecss rights for the user account used at the connection string.
Below will be my query.
SELECT `portaldb`.`users`.`full_name` AS 'Name of User'
,`Systemrevamp`.`System_countries`.`CountryName` AS 'Quoted For'
,`Systemrevamp`.`uniquequote`.`UniqueQuote` AS 'System Quote ID'
, IF (
LEFT(`Systemrevamp`.`uniquequote`.`username`, 1) = ' '
,'Web Access'
,'Bulk Upload'
) AS 'Type'
,DATE_FORMAT(`Systemrevamp`.`uniquequote`.`insertedon`, '%d-%b-%Y') AS 'Quoted On'
FROM `portaldb`.`users`
INNER JOIN `Systemrevamp`.`uniquequote` ON TRIM(`Systemrevamp`.`uniquequote`.`UserName`) = `portaldb`.`users`.`usrname`
INNER JOIN `Systemrevamp`.`System_countries` ON `Systemrevamp`.`System_countries`.`Code` = `Systemrevamp`.`uniquequote`.`CountryCode`
INNER JOIN `portaldb`.`permission_details` ON `portaldb`.`permission_details`.`user_ID` = `portaldb`.`users`.`user_ID`
WHERE `portaldb`.`permission_details`.`group_ID` = '5'
AND `Systemrevamp`.`uniquequote`.`insertedon` >= (NOW() - INTERVAL 3 MONTH)
ORDER BY `portaldb`.`users`.`full_name` ASC,`Systemrevamp`.`uniquequote`.`insertedon` ASC
Visual studio keeps telling me there is syntax error and to check the version of SQL, but I am able to retrieve at the database.
Part 2. Below is a snippet of my code. My question for this part is, if the above query is used, what source table should I put for the data adapter to fill at 'XXX'?
myDataAdapter = New MySqlDataAdapter(strSQL, myConnection)
allUserDataset = New DataSet()
myDataAdapter.Fill(allUserDataset, "XXX")
gvAllQuotes.DataSource = allUserDataset
gvAllQuotes.DataBind()
Please let me know if more information is needed. Thank you.

CakePHP Using "Group By" in Virtual Field Not Working

I have the following virtual field on my Page model
function __construct($id = false, $table = null, $ds = null) {
$this->virtualFields['fans'] = 'SELECT COUNT(Favorite.id) FROM favorites AS Favorite WHERE Favorite.page_id = Page.id AND Favorite.status = 0';
parent::__construct($id, $table, $ds);
}
This works as expected and displays the number of users who have added the page to their favorites. The issue is that, during development, some rows have duplicate user_id to page_id pairs so it returns the incorrect number or unique users. I tried adding a group by clause like so
$this->virtualFields['fans'] = 'SELECT COUNT(Favorite.id) FROM favorites AS Favorite WHERE Favorite.page_id = Page.id AND Favorite.status = 0 GROUP BY Favorite.user_id';
But it does not work. I tried debugging the issue but I receive the error message "allowed memory size exhausted". I also tried using SELECT COUNT('Favorite.user_id') and SELECT DISTINCT('Favorite.user_id') neither of which worked either. I believe DISTINCT is further away from the answer as that would return an array (I believe?)
Is this a known CakePHP issue? Am I implementing the group by wrong? Is there another solution to do this other than afterfind?
try this
SELECT COUNT(DISTINCT Favorite.user_id)
like that :
$this->virtualFields['fans'] = 'SELECT COUNT(DISTINCT id) FROM favorites WHERE status = 0';

Convert this code into active record/sql query

I have the following code and would like to convert the request into a mysql query. Right now I achieve the desired result using a manual .select (array method) on the data. This should be possibile with a single query (correct me if I am wrong).
Current code:
def self.active_companies(zip_code = nil)
if !zip_code
query = Company.locatable.not_deleted
else
query = Company.locatable.not_deleted.where("zip_code = ?", zip_code)
end
query.select do |company|
company.company_active?
end
end
# Check if the company can be considered as active
def company_active?(min_orders = 5, last_order_days_ago = 15)
if orders.count >= min_orders &&
orders.last.created_at >= last_order_days_ago.days.ago &&
active
return true
else
return false
end
end
Explanation:
I want to find out which companies are active. We have a company model and an orders model.
Data:
Company:
active
orders (associated orders)
Orders:
created_at
I don't know if it is possible to make the company_active? predicate a single SQL query, but I can offer an alternative:
If you do:
query = Company.locatable.not_deleted.includes(:orders)
All of the relevant orders will be loaded into the memory for future processing.
This will eliminate all the queries except for 2:
One to get the companies, and one to get all their associated orders.

Simplify sql query to obtain one line per id

I have a multi-table SQL query.
My need is: The query should I generate a single line by 'etablissement_id' ... and all information that I want to be back in the same query.
The problem is that this query is currently on a table where "establishment" may have "multiple photos" and suddenly, my query I currently generates several lines for the same id...
I want the following statement - LEFT JOINetablissementContenuMultimediaON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId - only a single multimedia content is displayed. Is it possible to do this in the query below?
Here is the generated query.
SELECT DISTINCT `etablissement`. * , `etablissementContenuMultimedia`. * , `misEnAvant`. * , `quartier`. *
FROM `etablissement`
LEFT JOIN `etablissementContenuMultimedia` ON etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId
LEFT JOIN `misEnAvant` ON misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id
LEFT JOIN `quartier` ON quartier_id = etablissement_quartierId
WHERE (
misEnAvant_typeMisEnAvantId =1
AND (
misEnAvant_dateDebut <= CURRENT_DATE
AND CURRENT_DATE <= misEnAvant_dateFin
)
)
AND (
etablissement_isActive =1
)
ORDER BY `etablissement`.`etablissement_id` ASC
LIMIT 0 , 30
Here is the code used ZF
public function find (){
$db = Zend_Db_Table::getDefaultAdapter();
$oSelect = $db->select();
$oSelect->distinct()
->from('etablissement')
->joinLeft('etablissementContenuMultimedia', 'etablissement.etablissement_id = etablissementContenuMultimedia.etablissementContenuMultimedia_etablissementId')
->joinLeft('misEnAvant', 'misEnAvant.misEnAvant_etablissementId = etablissement.etablissement_id')
->joinLeft('quartier', 'quartier_id = etablissement_quartierId ')
->where ('misEnAvant_typeMisEnAvantId = 1 AND (misEnAvant_dateDebut <= CURRENT_DATE AND CURRENT_DATE <= misEnAvant_dateFin) ')
->where ('etablissement_isActive = 1')
->order(new Zend_Db_Expr('RAND()'));
$zSql = $oSelect->__toString();
if(isset($_GET['debug']) AND $_GET['debug'] == 1)
echo $zSql ;
//die();
$oResultEtablissement = $db->fetchAll($oSelect);
return $oResultEtablissement ;
}
Can you help me?
Sincerely,
If you are looking to have only one of the media displayed out of many regardless of which it may be then you can just add a limit to the query? After that you can tweak the query for ASCending or DESCending perhaps?
Is this query supposed to have images (or image as it were) for one establishment, or one image each for each active establishment? I see you have a limit 0,30 which means you're likely paginating....
If the result you want is a search for only one establishment, and the first image it comes to would work fine .. just use "limit 1" and you'll only get one result.
I took the time to redo the whole model of the database ... and now it works. There was no solution for a system as flawed