PHP MySQL query with condition - php

I got stuck with a simple query which I can't figure out why isn't doing what I expect it to do. I have 3 values set on database like this:
$measure = 'kg';
$country_code = 'DE';
$weight = '5';
WEIGHT_UNIT | COUNTRIES | MAX_WEIGHT | PRICE
kg | DE,AT | 10 | 25.55
lbs | DE,AT,CH | 5 | 15.99
My PHP query looks like this:
SELECT *
FROM `article_shipping_options`
WHERE `weight_unit` = '$measure'
AND `countries` LIKE '%$country_code%'
AND `max_weight` <= '$weight'
LIMIT 1;
The result I was expecting was the row with the 25.55 price.
I know I am doing something wrong here despise my 2 days search on google...any help would be mostly appreciated :)

Did you mean MAX_WEIGHT >= $weight ?

I think you have the wrong inequality operator. Shouldn't it be max_weight >= '$weight'?

Try using FIND_IN_SET() and use max_weight >= '$weight'
SELECT *
FROM article_shipping_options
WHERE weight_unit='$measure' AND
FIND_IN_SET($country_code, countries) > 0 AND
max_weight >= '$weight'
LIMIT 1;
FIND_IN_SET()

You have $weight set to 5, but in the row's MAX_HEIGHT is 10.
Then the last condition for that row evaluates as 10 <= 5. Since the condition was not met, the row was not returned.

Related

Get value from table with 3 unique ID's (redundant sql query)

$query = "SELECT COUNT(id) FROM complaint WHERE ID_complntCategory = ?";
$complntCategory = $database->prepare($query);
try {
$complntCategory->execute(array());
$complntCategory->setFetchMode(PDO::FETCH_ASSOC);
foreach ($complntCategory as $key) {
$totaalM = $key['1'];
$totaalV = $key['2'];
$totaalG = $key['3'];
}
}
catch(PDOException $e) {
echo "Error";
}
Above you see my PHP code, and here is what I'm trying to do:
I'm trying to get the amount of rows from the table 'complaint' into 3 different variables (totaalM, totaalV and totaalG). The totaalM variable should contain the amount of rows 'WHERE ID_complntCategory = 1'.
For the other variables the 'ID_complntCategory' should be 2 and 3
('ID_complntCategory' is either 1, 2 or 3)
There should be a way where I don't have to write 3 queries, right?
I'm clearly approaching this the wrong way, and I'm not sure how I should tackle this problem...
What you are trying to do is called pivot rows into columns, but MySQL doesn't have pivot table operator like other RDBMS, but you cane use the case expression like this in one query:
SELECT
SUM(CASE WHEN ID_complntCategory = 1 THEN 1 ELSE 0 END) AS totaalM,
SUM(CASE WHEN ID_complntCategory = 2 THEN 1 ELSE 0 END) AS totaalV,
SUM(CASE WHEN ID_complntCategory = 3 THEN 1 ELSE 0 END) AS totaalG,
COUNT(Id) AS Total
FROM complaint;
Or you can make it shorter like this:
SELECT
SUM(ID_complntCategory = 1) AS totaalM,
SUM(ID_complntCategory = 2) AS totaalV,
SUM(ID_complntCategory = 3) AS totaalG,
COUNT(Id) AS Total
FROM complaint;
Demo
This will give you something like this:
| totaalM | totaalV | totaalG | Total |
|---------|---------|---------|-------|
| 2 | 3 | 1 | 7 |
Here you need some magic, involving special SQL and PDO features.
First, you need an SQL query that is giving you desired results in one query. To get that you need a GROUP BY operator:
SELECT ID_complntCategory, count(*) FROM complaint GROUP BY ID_complntCategory
it will give you counts split by ID_complntCategory.
Next, you can use one of PDO's magnificent features, PDO::FETCH_KEY_PAIR fetch mode, that will give you an array where key would be category id and value is count
$sql = "SELECT ID_complntCategory, count(*) FROM complaint GROUP BY ID_complntCategory";
$stmt = $database->prepare($sql);
$key = $stmt->fetchAll(PDO::FETCH_KEY_PAIR);
$totaalM = $key['1'];
$totaalV = $key['2'];
$totaalG = $key['3'];
note that you should never catch a PDO errors only to say "error". Let PHP error reporting to do it instead.

Get minimum values only for duplicates in table

I have the following SQL:
set #arbitraryMin = 'two weeks ago';
set #myDesiredMinimumTime = 'thisMorning';
select distinct order, box from db.table
where scantime >= #arbitraryMin
having min(scantime) >= #myDesiredMinimumTime
Essentially, we have a system where it is possible that there are multiple scans for a distinct box/order combo. I only want to get the ones where the minimum scantime is >= #myDesiredMinimumTime. The query above returns two columns with no values in them. I can do this with a sub query, but I was wondering if there was a way to do this without using one.
I am no SQL guru, so I appreciate any help. Table sample (sorry for format):
scantime | Order | Box
2017-06-29 12:34:56 | 123456 | 123
2107-06-29 12:12:12 | 123456 | 124
2017-06-28 14:50:00 | 123456 | 123
Note the two duplicate order/box combos on different days on rows 1 and 3. If I input my query with #arbitraryMin = '2017-06-28 00:00:00' and #myDesiredMinimumTime = '2017-06-29 00:00:00', I only want to get the last two rows, as the top one is a duplicate scan at a different time.
Thank you
That's a invalid SQL. You can't have a HAVING clause without GROUP BY. So the below line is faulty
having min(scantime) >= #myDesiredMinimumTime
You should put that condition in WHERE clause only
where scantime >= #arbitraryMin
and (select min(scantime) from db.table) >= #myDesiredMinimumTime
Thank you to Rahul.
I have found a solution:
select distinct order, box from db.table
where scantime <= #maxTime
group by ordernumber, boxnumber
having min(scantime) >= #myDesiredMinimumTime

Availability Calculating logic in php

This is a mysql query result. Now I have to calculate the available quantity in php based on per challan Id. The expected result will be:
ChallanId | Avaiable Qty | unitCostPrice | totalPrice
11 | 7 | 2 | 14
12 | 10 | 1 | 10
How it can be done in php? useing foreach or any other tricks.
Though you want to achieve this for PHP solution, but here I think SQL query also can do that:
select
ChallanId,
sum(case when Narration = 'in' then ItemIn when Narration = 'out' then 0 - ItemOut end) as Avaiable_Qty,
unitCostPrice,
sum(case when Narration = 'in' then ItemIn when Narration = 'out' then 0 - ItemOut end) * unitCostPrice as totalPrice
from (your query here...)
having Avaiable_Qty > 0
group by ChallanId
I would do the calculation in SQL by having a smarter query.
select
ChallanId,
UnitCostPrice,
sum(`ItemIn`)-sum(`ItemOut`) as AvailableQty,
(sum(`ItemIn`)-sum(`ItemOut`))*UnitCostPrice as totalPrice
from tbl
group by ChallanId
Live demo
This is psuedo-code kind of, since you didn't share your implementation with PHP.
Firstly, you can assume the Narration from whether ItemIn or ItemOut is not zero, in fact it is probably better to do that since you could then introduce items in as well as items out with the same line. But that's not the question.
$output = array();
foreach ($dbResults as $row) {
// Create an output entry
if (!array_key_exists($row['ChallanID'], $output)) {
$output[$row['ChallanID']] = array('Qty' => 0, 'CostPrice' => 0, 'Total' => 0);
}
// Add to totals
$output[$row['ChallanID']]['Qty'] += ($row['ItemIn'] - $row['ItemOut']);
$output[$row['ChallanID']]['CostPrice'] = $row['UnitCostPrice']; // you may want to average this instead?
$output[$row['ChallanID']]['Total'] += $output[$row['ChallanID']]['Qty'] * $output[$row['ChallanID']]['CostPrice'];
}
$output should now contain your desired output. Untested.

Using OR and AND in MySQL

I have a query as follow: (shows are a table with tv shows and IMDB ID and recommended_titles is a table with two columns with IMDB_ID)
Select t2.* from shows t, shows t2, recommended_titles WHERE
t.imdb_id = recommended_titles. title_id_1
AND recommended_titles.title_id_2=t2.imdb_id
AND t.imdb_id = 0367279 LIMIT 7
The query is fine but I realized that it was only checking in the first column for my imdb id when it can also appear in my second one.
So i try to add the following:
OR
recommended_titles.title_id_2=t.imdb_id
AND t.imdb_id = recommended_titles. title_id_1
AND t.imdb_id = 0367279 LIMIT 7
But apparently OR can't be used with AND,
any suggestions as how I should do this ?
Edit:
To explain what I'm trying to do, here's a quick example in case my explanations above are too confusing.
table shows has rows like this:
name of a tv show | 00001
name of another | 00002
name of another | 00003
table recommended titles has (notice that an ID can be in either column)
00001 | 00002
00002 | 00003
You may look at operator precedence in mysql (and see that AND has an higher precedence than OR), or use parenthesis (much easier to use and maintain)
(t.imdb_id = recommended_titles.title_id_1 OR
recommended_titles.title_id_2=t.imdb_id)
AND recommended_titles.title_id_2=t2.imdb_id
AND t.imdb_id = 0367279 LIMIT 7
Do it like this,
(recommended_titles.title_id_2=t.imdb_id
OR t.imdb_id = recommended_titles. title_id_1)
AND t.imdb_id = 0367279 LIMIT 7
(t.imdb_id = recommended_titles. title_id_1
OR recommended_titles.title_id_2=t.imdb_id )
AND t.imdb_id = 0367279 LIMIT 7
Just use parenthesis to group your conditions for priorities.

How to find the sum of two colums with a quantity value

Ok so I am a lil confused how to go about this and seek some help..
I have a mysql db that has a column named quantity and another called price_paid
what I want to do is take and add up the entire column of price_paid but to also take into account a quantity higher than 1.
Ex..
_____________ ______________
| quantity | | price_paid |
-------------- ---------------
1 2.99
2 9.99
1 1.99
How would I create the php / mysql to make that = a total of 24.96 ?
So far I am able to get the total of price_paid but what I have doesn't take into account the quantity column and it's value.
$comic_totals = "SELECT sum(price_paid) AS value_sum FROM `comic_db`.`comic_db`";
$total_db = mysqli_query($comic_connect, $comic_totals);
if(!total_db){
echo "Failed";
}
$tot_array = mysqli_fetch_assoc($total_db);
$sum = $tot_array['value_sum'];
echo "$".$sum;
so how do I turn that into what I need? Thanks
Let MySQL take care of multiplying the price by the quantity...
SELECT SUM(quantity * price_paid) AS value_sum
If you want quantity higher than 1 then add where clause
Like this
SELCET SUM(quantity * price_paid) as value
FROM comic_db.comic_db
WHERE quantity > 1;

Categories