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
Related
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?
I got three tables : http://sqlfiddle.com/#!2/c7317
I want to get this output per row:
ProductId = 1
ProductCode = 1
ProductRetailPrice = 1
SubProductThumb = 1.jpg (the first subproducts thumb, where ProductId = 1)
Sub Products of ProductId 1
---------------------------
SubProductId = 1
SubProductPieces = 10
SubProductId = 4
SubProductPieces = 40
SubProductId = 7
SubProductPieces = 70
I got this code working with MySQL :
$show_product_content = mysql_query("
SELECT DISTINCT a.`ProductId`, a.`ProductCode`, a.`ProductRetailPrice`, a.`ProductPrice`, a.`ProductOffer`, a.`ProductTopSeler`, a.`ProductStrass`, a.`ProductStatus`, b.`SubProductThumb`
FROM `Products` as a, `SubProducts` as b
WHERE b.ProductId=a.ProductId
GROUP BY a.`ProductId`
");
while($row = mysql_fetch_array($show_product_content))
{
echo '<br />ProductId = '.$row['ProductId'].'<br />';
echo 'ProductCode = '.$row['ProductCode'].'<br />';
echo 'ProductRetailPrice = '.$row['ProductRetailPrice'].'<br />';
echo 'SubProductThumb = '. $row['SubProductThumb'].'<br /><br />';
$product_id = $row['ProductId'];
$show_sub_product_content = mysql_query("
SELECT SubProductId, SubProductPieces, SubProductStatus, SubProductRingSize6, SubProductRingSize7, SubProductRingSize8, SubProductRingSize9, c1.ColorHex as Color1, c1.ColorName as ColorName1, c2.ColorHex as Color2, c2.ColorName as ColorName2
FROM SubProducts
INNER JOIN Colors c1 ON c1.ColorId=SubProducts.SubProductColor1
INNER JOIN Colors c2 ON c2.ColorId=SubProducts.SubProductColor2
WHERE ProductId='$product_id'
");
echo 'Sub Products of ProductId '.$product_id.'<br />------------------------------------<br />';
while($row = mysql_fetch_array($show_sub_product_content))
{
echo 'SubProductId = '.$row['SubProductId'].'<br />';
echo 'SubProductPieces = '.$row['SubProductPieces'].'<br /><br />';
}
}
but i want to do this with prepare statement and single query, is this possible?
Your single query is below, i combined your two queries.
SELECT a.`ProductId`, a.`ProductCode`, a.`ProductRetailPrice`, a.`ProductPrice`, a.`ProductOffer`, a.`ProductTopSeler`, a.`ProductStrass`, a.`ProductStatus`, b.`SubProductThumb`, b.SubProductId, b.SubProductPieces, b.SubProductStatus, b.SubProductRingSize6, b.SubProductRingSize7, b.SubProductRingSize8, b.SubProductRingSize9, c1.ColorHex as Color1, c1.ColorName as ColorName1, c2.ColorHex as Color2, c2.ColorName as ColorName2
FROM `Products` as a, `SubProducts` as b
LEFT JOIN Colors c1 ON c1.ColorId=b.SubProductColor1
LEFT JOIN Colors c2 ON c2.ColorId=b.SubProductColor2
WHERE b.ProductId=a.ProductId
GROUP BY a.`ProductId`
I think that a LEFT JOIN should be useful in that specific case.
I am doing some tests, I will let you know.
we have a script that has been provided from our developers for php to generate a best sellers list from our database, however we need it to be in coldfusion!
Is there a simple way to convert or will this need rewriting completely?
Thanks in advance for any advice :-)
// // ---------- // Get Top Selling Products (by sku) // ---------- //
function CWgetBestSelling($max_products=5, $sub_ids=0)
{
$productQuery = '';
$returnQuery = '';
$idList = '0';
$itemsToAdd = '';
if (!is_numeric($idList[0])) {
$idList = '0';
}
$q_productQuery = mysql_query( "
SELECT count(*) as prod_counter,
p.product_id,
p.product_name,
p.product_preview_description,
p.product_date_modified
FROM cw_products p
INNER JOIN cw_order_skus o
INNER JOIN cw_skus s
WHERE o.ordersku_sku = s.sku_id
AND s.sku_product_id = p.product_id
AND NOT p.product_on_web = 0
AND NOT p.product_archive = 1
AND NOT s.sku_on_web = 0
GROUP BY product_id
ORDER BY prod_counter DESC
LIMIT ".$max_products
,$_ENV["request.cwapp"]["db_link"]);
$productQuery = array();
while ($qd = mysql_fetch_assoc($q_productQuery)) {
$productQuery[] = $qd;
}
// add values to list
foreach ($productQuery as $values) {
$idList = $values['product_id'] . "," . $idList;
}
// if not enough results, fill in from sub_ids
if (count($productQuery) < $max_products) {
// number needed
$itemsToAdd = $max_products - count($productQuery);
for ($i = 1; $i <= $itemsToAdd; $i++) {
if (substr_count($sub_ids, ',') >= $i) {
$idListArray = explode(',', $sub_ids);
$idList .= "," . $idListArray[$i];
}
}
$q_resultsQuery = mysql_query("
SELECT 0 as prod_counter,
p.product_id,
p.product_name,
p.product_preview_description,
p.product_date_modified
FROM cw_products p
WHERE p.product_id in(".CWqueryParam($idList).")
AND NOT p.product_on_web = 0
AND NOT p.product_archive = 1
ORDER BY product_date_modified DESC
",$_ENV["request.cwapp"]["db_link"]);
} else {
$q_resultsQuery = mysql_query("
SELECT count(*) as prod_counter,
p.product_id,
p.product_name,
p.product_preview_description,
p.product_date_modified
FROM cw_products p
INNER JOIN cw_order_skus o
INNER JOIN cw_skus s
WHERE o.ordersku_sku = s.sku_id
AND s.sku_product_id = p.product_id
AND NOT p.product_on_web = 0
AND NOT p.product_archive = 1
AND NOT s.sku_on_web = 0
GROUP BY product_id
ORDER BY prod_counter DESC, product_date_modified
",$_ENV["request.cwapp"]["db_link"]);
}
while ($qd = mysql_fetch_assoc($q_resultsQuery)) {
$returnQuery[] = $qd;
}
return $returnQuery;
}
Code conversion questions don't tend to stay open long because they're viewed as lazy. So, Here are some references to get you started. I'm no PHP pro but after a quick glance at your code I think this list of links will give you a good head start.
CFFunction
CFQuery
CFArgument
valueList()
CFLoop
CFif
In the interest of not doing your work for you and give you the opportunity to learn, I'll provide some samples but not the entire code so you get an idea where your PHP fits into CF. This is also the tag version, not the script version.
<cffunction name = "CWgetBestSelling" ...>
<cfargument name = "max_products" default = "5" ...>
<cfargument ...>
<cfset var local.productQuery = "">
<cfset var local.returnQuery = "">
<cfset ...>
<cfset ...>
<cfquery name = "q_productQuery " datasource = "yourDatasource">
SELECT
count(*) as prod_counter,
p.product_id,
p.product_name,
p.product_preview_description,
p.product_date_modified
FROM
cw_products p
INNER JOIN cw_order_skus o
INNER JOIN cw_skus s
WHERE
o.ordersku_sku = s.sku_id
AND s.sku_product_id = p.product_id
AND NOT p.product_on_web = 0
AND NOT p.product_archive = 1
AND NOT s.sku_on_web = 0
GROUP BY
product_id
ORDER BY
prod_counter DESC
LIMIT #arguments.max_products#
</cfquery>
...
...
...
<cfreturn yourReturnVariable>
</cffunction>
I have this snippet that shows all taxonomy list in the site, that belongs to a specific vocabulary.
Instead of printing the whole list, how do I just print the terms that belong to the node I'm actually loading?
I have a Drupal 7 installation.
This is how I print the id of the node I´m at: <?php print $node->nid;?>
<?php
$vid = 11; //vocabulary id
$query = "SELECT tid, name, count
FROM (
SELECT td.tid AS tid, name, COUNT(td.tid) AS count
FROM taxonomy_term_data AS td
JOIN taxonomy_index AS tn
ON td.tid = tn.tid
JOIN node AS n
ON n.nid = tn.nid
WHERE td.vid = ". $vid ."
AND n.status = 1
GROUP BY td.tid
ORDER BY count DESC
) AS t
ORDER BY name ASC";
$result = db_query($query);
foreach($result as $term) {
if ($term->count > 0) {
echo l($term->name, "taxonomy/term/$term->tid").' ('.$term->count.')'.'<br/>';
}
}
?>
I would suggest not to run extra query for this.
This information should be available in $node object.
Just print it [print_r($node) ] and see what exactly is the taxonomy object name($node->taxonomy) & how taxonomy information is structured & use that to display category on node page or node teaser.
On other pages, you can use node_load to 1st load the node and then do the same thing.
sumoand's answer is more optimal in this case, however for some sql practicing here's the exact solution the way you imagined:
<?php
$vid = 11; //vocabulary id
$query = "SELECT tid, name, count
FROM (
SELECT td.tid AS tid, name, COUNT(td.tid) AS count
FROM taxonomy_term_data AS td
JOIN taxonomy_index AS tn
ON td.tid = tn.tid
JOIN node AS n
ON n.nid = tn.nid
WHERE td.vid = ". $vid ."
AND n.status = 1
AND n.nid = ".$node->id."
GROUP BY td.tid
ORDER BY count DESC
) AS t
ORDER BY name ASC";
$result = db_query($query);
foreach($result as $term) {
if ($term->count > 0) {
echo l($term->name, "taxonomy/term/$term->tid").' ('.$term->count.')'.'<br/>';
}
}
?>
Well I have gotten this query:
$characterinfoquery = "
SELECT
c.Name,
c.Level,
c.Sex,
c.Playtime,
c.KillCount,
c.DeathCount,
cl.Name AS clanName
FROM
Character AS c,
Account AS a,
ClanMember AS cm,
Clan AS cl
WHERE
c.AccountID = a.AccountID AND
c.CharacterID = cm.CharacterID AND
cm.ClanID = cl.ClanID AND
a.UserID='".mssql_real_escape_string($_SESSION['username'])."'
";
But I want the members who do not have a clan to be showed too but instead of the clan name it would say "-" at where the clan name is supposed to be.
This is my while statement:
if(mssql_num_rows($characterinforesult) != 0){
$content = str_replace("%content%", file_get_contents("tpl/contents/characterinfo.html"), $content);
//Get character information
$search = array("%Name%", "%Level%", "%Sex%", "%Playtime%", "%KillDeath%", "%Clan%");
$rows = file_get_contents("tpl/contents/characterinfo_tr.html");
while($row = mssql_fetch_assoc($characterinforesult)){
if($row['KillCount'] != 0){
$KillDeath = round($row['KillCount']/$row['DeathCount'], 2);
}
else{
$KillDeath = "-";
}
$Playtime = $row['Playtime']/60;
$replace = array($row['Name'], $row['Level'], gender($row['Sex']), round($Playtime), $KillDeath, $row['clanName']);
$tr .= str_replace($search, $replace, $rows);
}
}
Could someone help me with this?
Output with innerjoins:
Name Level Sex Playtime K/D Ratio Clan
DragonDex 97 Male 375 min 0.22 Test
It shows 1 row while there are 2 characters in that account, 1 has a clan the other doesn't.
Do you need a left outer join:
SELECT
c.Name,
c.Level,
c.Sex,
c.Playtime,
c.KillCount,
c.DeathCount,
coalesce( cl.Name, ' - ' ) AS clanName
FROM
Character AS c
inner join
Account AS a
on c.AccountID = a.AccountID
left outer join
ClanMember AS cm
on c.CharacterID = cm.CharacterID
left outer join
Clan AS cl
on cm.ClanID = cl.ClanID
WHERE
a.UserID='".mssq ...