Cumulate count querys with mysql and GROUP BY - php

In the following fictionalized example, there is the (main) table country_sales.
In each added record can be added several cars and several radios.
I need to make cumulative queries for a search/count component.
if ($group == 'cars'){
$query = "SELECT COUNT (cs.id_cars) AS total, tc.desc_cars AS isname
FROM cars_sold cs, tab_cars tc, country_sales csa
WHERE csa.status = 1
AND tc.id_cars = cs.id_cars
AND csa.id_name = tc.id_name ";
}
if ($group == 'extras'){
$query = "SELECT COUNT (es.id_radio) AS total, tc.desc_radio AS isname
FROM radio_sold es, tab_radio tex, country_sales csa
WHERE csa.status = 1
AND tex.id_radio = es.id_radio
AND csa.id_name = tex.id_name ";
}
if($cars > 0 ){
$query .= " AND csa.id_name IN(SELECT id_name FROM tab_cars WHERE id_cars = ? )";
}
if($extras > 0 ){
$query .= " AND csa.id_name IN(SELECT id_name FROM tab_extras WHERE id_extras = ? )";
}
$query .= " GROUP BY isname";
If the option is group (by) cars and the car is Ford Mustang, I get not only the number of Ford Mustang cars sold, but also a list of all other models sold.
The same is true for radios sold.
If the query cumulates cars and radios works but still displays a list of all cars or all radios sold according to the criteria GROUP BY
What I try to achieve is to get only one row with the desired count. For example and only 80 Ford Mustang.
I tried the following:
if ($group == 'cars'){
$query = "SELECT COUNT (cs.id_cars) AS total, tc.desc_cars AS isname
FROM cars_sold cs
LEFT JOIN tab_cars tc ON cs.id_cars = tc.id_cars
LEFT JOIN country_sales csa ON tc.id_name = csa.id_name
WHERE csa.status = 1 ";
}
if ($group == 'extras'){
$query = "SELECT COUNT (es.id_radio) AS total, tc.desc_radio AS isname
FROM radio_sold es
LEFT JOIN tab_radio tex ON es.id_radio = tex.id_radio
LEFT JOIN country_sales csa ON tex.id_name = csa.id_name
country_sales csa
WHERE csa.status = 1 ";
}
if($cars > 0 ){
$query .= " AND id_cars = ? ";
}
if($extras > 0 ){
$query .= " AND id_extras = ? ";
}
$query .= " GROUP BY isname";
Problem:
If I search by cars or radio, I get a single row with the desired result.
However cumulate querys for cars and radios does not work.
Any ideas how to solve it?

Related

From PHP how to efficiently execute this search in SQL Server?

I have a database structure something like the following:
Table A: PersonId, GroupId
Table B: GroupId, ParentGroupId
Given a PersonId, I want to find the Ids of all people in parent groups of that person's group.
First I select the ParentGroupId for the given PersonId, by joining with B. Then I do a while loop, selecting and recording the PersonId from A based on the GroupId returned in the previous search, and continue the loop by obtaining the next ParentGroupId from B.
Is this an efficient way to do this search, or is there an option that does not involve a while to "bubble up" in this manner?
(this is a simplified version of the actual scenario, changing the schema is not an option)
$sql = 'SELECT ParentGroupID FROM A WHERE PersonId = ' . $id;
$result = $db->query($sql);
$row = $db->fetch_array($result);
$parent_group = $row['ParentGroupId'];
if(!is_null($parent_group)) {
$parent_ids = array();
while($parent_group > 0) {
//is there a way to do this where I retrieve all managers <= lvl 6 at once, so I don't have to loop in order to 'tier up'?
$sql = 'SELECT ParentGroupID, PersonID
FROM B
INNER JOIN A on ParentGroupID = A.GroupID
WHERE ParentGroupID = ' . $parent_group;
$result = $db->query($sql);
$row = $db->fetch_array($result);
$parent_group = $row['ParentGroupID'];
$parent_ids[] = $row['PersonID'];
}
}
Combining your two queries into one would be more efficient:
$sql = 'SELECT ParentGroupID, PersonID
FROM B
INNER JOIN A on ParentGroupID = A.GroupID
WHERE ParentGroupID IN (
SELECT ParentGroupID FROM A WHERE ParentGroupID > 0
AND PersonId = ' . $id .')' ;

How to write MySQL aliases properly?

For all those that care, I found that I needed to re read the basics on querying. Once sorted, I realised I had a fair few errors throughout my code.
I've got a query I'm trying to build and I'm throwing up error after error regarding to ambiguity. Would anyone kindly show me how to execute MySQL aliases properly?
This is my code so far. It worked fine until I put the join in there. I suspect it's because I'm referencing 'wine' more than once in the same query, but that may be one of many problems.
$query =
"SELECT
wine_id,
wine_name,
winery_name,
region_name,
year,
variety
FROM
wine AS w,
winery,
region,
grape_variety
JOIN
wine
ON
grape_variety.variety_id = wine.wine_id
JOIN
wine_variety
ON
wine.wine_id = wine_variety.variety_id
WHERE
winery.region_id = region.region_id
AND
wine.winery_id = winery.winery_id";
if (!empty($wineName)) {
$query .= " AND wine_name = '{$wineName}'";
}
if (!empty($wineryName)) {
$query .= " AND winery_name = '{$wineryName}'";
}
// If the user has specified a region, add the regionName
// as an AND clause
if (isset($regionName) && $regionName != "All") {
$query .= " AND region_name = '{$regionName}'";
}
// If the user has specified a variety, add the grapeVariety
// as an AND clause
if (isset($grapeVariety) && $grapeVariety != "Riesling") {
$query .= " AND variety = '{$grapeVariety}'";
}
Try to do it this way:
SELECT w.wine_id, w.wine_name, winery_name, region_name, year, variety
FROM
wine AS w
join winery on w.winery_id = winery.winery_id
join region on winery.region_id = region.region_id,
join grape_variety on grape_variety.variety_id = w.wine_id
Your query must be like:
SELECT
w.wine_id,
w.wine_name,
wy.winery_name,-- I assume this column from table `wy`
r.region_name, -- column from table `region`
w.year,
w.variety
FROM wine w
INNER JOIN winery wy ON (wy.winery_id = w.winery_id )
INNER JOIN region r ON ( r.region_id = wy.region_id )
INNER JOIN grape_variety gv ON (gv.variety_id = w.wine_id)
INNER JOIN wine_variety wv ON (wv.variety_id = w.wine_id)
...
append other WHERE conditions here
Note: if you give table structure then it would be more clear, at first I assume whatever column you retrieve is from main table and
if all tables in query have same column name then use table_alias_name.column_name.
try this
SELECT
w.wine_id,
w.wine_name,
wy.winery_name,
r.region_name,
r.year,
wv.variety
FROM wine w
INNER JOIN winery wy ON (wy.winery_id = w.winery_id )
INNER JOIN region r ON ( r.region_id = wy.region_id )
INNER JOIN grape_variety gv ON (gv.variety_id = w.wine_id)
INNER JOIN wine_variety wv ON (wv.variety_id = w.wine_id)
Use This one
$query =
"SELECT
w.wine_id,
w.wine_name,
winery.winery_name,
region.region_name,
year,
grape_variety.variety
FROM
wine AS w,
winery,
region,
grape_variety
JOIN
wine
ON
grape_variety.variety_id = wine.wine_id
JOIN
wine_variety
ON
wine.wine_id = wine_variety.variety_id
WHERE
winery.region_id = region.region_id
AND
wine.winery_id = winery.winery_id";
if (!empty($wineName)) {
$query .= " AND w.wine_name = '{$wineName}'";
}
if (!empty($wineryName)) {
$query .= " AND winery.winery_name = '{$wineryName}'";
}
// If the user has specified a region, add the regionName
// as an AND clause
if (isset($regionName) && $regionName != "All") {
$query .= " AND region.region_name = '{$regionName}'";
}
// If the user has specified a variety, add the grapeVariety
// as an AND clause
if (isset($grapeVariety) && $grapeVariety != "Riesling") {
$query .= " AND grape_variety.variety = '{$grapeVariety}'";
}

Displaying a list with numerous values

I was hoping somebody may be able to help with my problem.
I am using the following query
$query = $db->prepare("SELECT p.pattern_for,
c_main.name AS cat_name, c_main.slug AS cat_slug,
c_sub.name AS sub_cat_name, c_sub.slug AS sub_cat_slug
FROM products AS p
INNER JOIN categories AS c_main ON c_main.name = p.c_main
INNER JOIN categories AS c_sub ON c_sub.name = p.c_sub
WHERE p.stock_level > 0 AND p.pattern_for != ''
GROUP BY p.pattern_for
ORDER BY p.pattern_for ASC");
$query->execute();
The above works fine however I want to give the person creating the products the ability to be able to add numerous values to the column 'pattern_for'.
So it could have the following values -
Product A - 'Men, Women, Children
Product B - 'Women'
Product C - 'Toddlers, Girls'
Product D - 'Men, Boys'
Product E - 'Girls, Women, Babies'
What I need it to do is (in the query) split the values using the comma and then display them all in a list but also grouping them so it only shows once and also ordering alphabetically.
So for example the output of the above would be...
Babies
Boys
Children
Girls
Men
Toddlers
Women
Is this possible?
For those who may come across this problem in the future here is the query I ended up using...
$query_pattern_for = $db->prepare("SELECT p.pattern_for,
c_main.name AS cat_name, c_main.slug AS cat_slug,
c_sub.name AS sub_cat_name, c_sub.slug AS sub_cat_slug
FROM products AS p
INNER JOIN categories AS c_main ON c_main.name = p.c_main
INNER JOIN categories AS c_sub ON c_sub.name = p.c_sub
WHERE c_main.type = 0 AND c_sub.type = 0 AND p.stock_level = 0 AND p.reorder = 0 AND p.pattern_for != '' AND p.status = 1
OR c_main.type = 0 AND c_sub.type = 0 AND p.stock_level > 0 AND p.pattern_for != '' AND p.status = 1
GROUP BY pattern_for
ORDER BY p.pattern_for ASC");
$query_pattern_for->execute();
$count_pattern_for = $query_pattern_for->rowCount();
and then the php...
while ($row = $query_pattern_for->fetch(PDO::FETCH_ASSOC)) {
$get_pattern_for .= $row['pattern_for'] . ',';
}
$get_pattern_for = str_replace(', ', ',', $get_pattern_for);
$get_pattern_for = explode(",", $get_pattern_for);
$get_pattern_for = array_unique($get_pattern_for);
$get_pattern_for = array_filter($get_pattern_for);
sort($get_pattern_for);
foreach($get_pattern_for as $pattern_for) {
$pattern_for_slug = str_replace(' ','',$pattern_for);
$pattern_for_slug = str_replace('/','-',$pattern_for_slug);
$pattern_for_slug = preg_replace('/[^\w-]/', '', $pattern_for_slug);
$pattern_for_slug = strtolower($pattern_for_slug);
echo '<li>'; if ($get_patterns_for == $pattern_for_slug) { echo '<div class="tick-box-selected">✔</div>'.$pattern_for.''; } else { echo '<div class="tick-box"></div>'.$pattern_for.''; } echo '</li>';
}
I hope this helps somebody out someday.
Thank you
Dan

how to create the sql_query

I have created some filters in php.3 of them are aimming 1 table. The 4th is aimming another table.
first table is :
id_of_orders :
id_order(int) time(NOW) username(varchar) price(decimal)
the second one is :
order :
order_id(int) product(varchar) price (decimal)
order.order_id is refered to the id_of_orders.id_order
Table id_of_orders is like a mapper to the orders table (id_of_orders.id_order has unique numbers).
Table orders contains many orders some of them have same order_id
I want to return the id_of_orders.id_order which contain the order.product=='proion'
The query that i use is this:
$query = "SELECT * FROM id_of_orders WHERE 1=1";
if(!empty($_SESSION['employees']))
$query .= " AND id_of_orders.username='$_SESSION[employees]'";
if(!empty($_SESSION['timis']))
$query .= " AND id_of_orders.price='$_SESSION[timis]'";
if(!empty($_SESSION['dates']))
$query .= " AND DATE(time)='$_SESSION[dates]'";
//if(!empty($_SESSION['proions']))
// $query .= " AND (orders.product='$_SESSION[proions]' && id_of_orders.id_order==orders.order_id)";
$result = mysql_query($query);
You can try a query like
SELECT o.*
FROM id_of_orders i JOIN
(
SELECT order_id
FROM orders
WHERE product = 'proion'
GROUP BY order_id
) q ON i.id_order = q.order_id
WHERE o.username = ?
AND o.price = ?
AND DATE(time) = ?
or
SELECT i.id_order, i.time, i.username, i.price
FROM id_of_orders i JOIN orders o
ON i.id_order = o.order_id
WHERE 1 = 1
AND o.product = 'proion'
AND o.username = ?
AND o.price = ?
AND DATE(time) = ?
GROUP BY i.id_order, i.time, i.username, i.price

MySQL Query Not Working PHP

I have a query I'm trying to build so that I can filter by car brand. But if a certain session variable exists, it'll ask for an extra part to be added to the query which is basically limiting the results to the logged in branch. Here's the query:
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON a.aCarBrandID = b.bid
ORDER BY b.brand $orderx";
... now this works but where can I add a:
"WHERE bid = '{$bid}'"? ...or a... "AND bid = '{$bid}'";
It brings up an error.
insert your where clauses BEFORE your order by
$query_AUCTION = "SELECT * FROM at_auction AS a JOIN at_brands AS b ON a.aCarBrandID = b.bid WHERE bid = '{$bid}' ORDER BY b.brand $orderx";
Use a generic WHERE 1=1 and if you want to insert additional condition:
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON a.aCarBrandID = b.bid
WHERE 1=1 ";
if ($bid > 0)
$query_AUCTION .= " AND bid = '{$bid}' ";
$query_AUCTION .= " ORDER BY b.brand $orderx";
try this :
$query_AUCTION = "SELECT *
FROM at_auction AS a
JOIN at_brands AS b ON ( b.bid = a.aCarBrandID ) ";
if( isset( $_SESSION['bid'] ) )
{
$query_AUCTION.= " WHERE b.bid = '".$_SESSION['bid']."'";
}
$query_AUCTION.= " ORDER BY b.brand $orderx";

Categories