I'm developing a web application that works with WordPress database. In my website,(which works with WooCommerce and WPML) I have products in two languages - english (1st), serbian(2nd). I wrote an SQL code that get the products from database, with their regular and sale prices and etc., but I want to get ONLY products where lang = en (the products from english version). The problem is I don't know how to get them.
Simple SQL:
$sql = 'SELECT * from `wp_posts` WHERE post_type = product';
This is the method that SELECT from database:
// SELECT
public function select (
$table_1 = ' wp_posts ',
$table_2 = ' wp_postmeta ',
$rows = ' t1.id, t1.post_title, guid, post_type ',
$where = ' t1.post_status = "publish" AND t1.post_type = "product" OR t1.post_type = "product_variation" ',
$groupby = ' t1.ID, t1.post_title '
) {
// Connect to database and set charset
$this->connect();
$this->conn->set_charset('utf8');
// Published products
$sql = "SELECT $rows,
max(case when meta_key = '_regular_price' then t2.meta_value end) AS price,
max(case when meta_key = '_sale_price' then t2.meta_value end) AS sale,
max(case when meta_key = 'attribute_colors' then t2.meta_value end) AS colors,
max(case when meta_key = 'attribute_number' then t2.meta_value end)
FROM $table_1 AS t1
INNER JOIN $table_2 AS t2 ON ( t1.ID = t2.post_id )
WHERE $where
GROUP BY $groupby";
$result = mysqli_query($this->conn, $sql);
$published_products_count = mysqli_num_rows($result);
// Trashed products
$trashed_sql = "SELECT post_status FROM `wp_posts`
WHERE post_status = 'trash'";
$trashed_result = mysqli_query($this->conn, $trashed_sql);
$trashed_products_count = mysqli_num_rows($trashed_result);
// If results -> show them
if ($result) {
printf( "\t\t" . "<p>There are <strong>%d published</strong> products and <strong>%d trashed</strong>.</p>", $published_products_count, $trashed_products_count);
$table = '
<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th>Row. №</th>
<th>ID</th>
<th>Product</th>
<th>Regular price</th>
<th>Sale price</th>
<th>Type</th>
<th>Edit</th>
</tr>
</thead>';
$row_number = 1;
while ($row = $result->fetch_assoc()) {
$table .= '
<tr>
<td>' . $row_number++ . '</td>
<td>' . $row["id"] . '</td>
<td>' . $row["post_title"] . '</td>
<td class="price">' . $row["price"] . '</td>
<td class="sale">' . $row["sale"] . '</td>
<td>' . $row["post_type"] . '</td>
<td>Edit</td>
</tr>';
}
$table .= '
</table>';
echo $table;
}
// If no results
else {
echo 'There isn't any products';
}
}
I hope somebody help me!
Thanks in advance! :)
P.S. The application is not based on WordPress!
WPML plugin creates several new tables to manage multilang, not affecting the standard WP posts tables. Specifically, it creates the wp_icl_translations table, where it stores relations between posts and languages.
You need to add two new JOIN statements to your query:
JOIN wp_icl_translations t ON wp_posts.ID = t.element_id AND t.element_type = 'post_product' JOIN wp_icl_languages l ON t.language_code=l.code AND l.active=1
Then, you can add a new condition to your WHERE statement like this:
AND t.language_code='en'
Hope this helps.
Regards.
Related
I have a query that works (see query results) temporarily taken out I don't have enough points for more than two links
However, when I try to output in PHP the category name is the same for both the offeredcategory.categoryName and wantedcategory.categoryName for categoryName on output to a table (see screenshot):
I'm trying to use the alias in the query to output categoryName differently for offered and wanted.
I've also tried using $row["offeredcategory.categoryName"] and $row["wantedcategory.categoryName"] which yields an error:
Notice: Undefined index: offeredcategory.categoryName in C:\Program Files (x86)
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $connection->connect_error);
}
$sql = "SELECT customers.*, ads.*, categoriesselected.categoryselectedID, categoriesselected.offeredcategoryID, offeredcategory.categoryID, offeredcategory.categoryName, categoriesselected.wantedcategoryID, wantedcategory.categoryID, wantedcategory.categoryName
FROM customers
INNER JOIN ads ON ads.customerId = customers.customerID
INNER JOIN categoriesselected ON categoriesselected.adID = ads.adID
LEFT OUTER JOIN categories AS offeredcategory ON offeredcategory.categoryID = categoriesselected.offeredcategoryID
LEFT OUTER JOIN categories AS wantedcategory ON wantedcategory.categoryID = categoriesselected.wantedcategoryID";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table>
<tr><th></th><th colspan=2>OFFERING</th><th colspan=2>WANTING</th><th>Location</th></tr>";
//need to prevent SQL injection using ...
while($row = $result->fetch_assoc())
{
echo
'<tr>
<td><img src="images/'.$row["fileUploadLocation"]. '" width="80" height="80" class="descImage"/></td>
<td>' ."<h6>" . $row["categoryName"]. "</h6>" . "<br>"
. $row["servicesOfferedTitle"]. '</td>
<td>' . $row["servicesOfferedDescription"]. '</td>
<td>' . $row["categoryName"]. "<br>"
. $row["servicesWantedTitle"]. '</td>
<td>' . $row["servicesWantedDescription"]. ' </td>
<td>' . $row["location"]. '</td>
</tr>';
}
echo "</table>";
} else {
echo "0 results";
}
I've now tried as suggested changing alias from joins to Select but now the joins won't work
Haven't to the $row part yet.
I've now tried as suggested changing alias from joins to Select but now the joins won't work (see screenshots):
Haven't to the $row part yet.
from manasschlcatz
Next tried 2nd suggestion but yields error:
Notice: Undefined index: offeredName in C:\Program Files (x86)
$sql = "SELECT customers.*, ads.*, categoriesselected.categoryselectedID, categoriesselected.offeredcategoryID, offeredName.categoryID, offeredName.categoryName, categoriesselected.wantedcategoryID, wantedName.categoryID, wantedName.categoryName
FROM customers
INNER JOIN ads ON ads.customerId = customers.customerID
INNER JOIN categoriesselected ON categoriesselected.adID = ads.adID
LEFT OUTER JOIN categories AS offeredName ON offeredName.categoryID = categoriesselected.offeredcategoryID
LEFT OUTER JOIN categories AS wantedName ON wantedName.categoryID = categoriesselected.wantedcategoryID" ;
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "<table>
<tr><th></th><th colspan=2>OFFERING</th><th colspan=2>WANTING</th><th>Location</th></tr>";
//need to prevent SQL injection using ...
while($row = $result->fetch_assoc())
{
echo
'<tr>
<td><img src="images/'.$row["fileUploadLocation"]. '" width="80" height="80" class="descImage"/></td>
<td>' . $row["offeredName"]. "<br>"
. $row["servicesOfferedTitle"]. '</td>
<td>' . $row["servicesOfferedDescription"]. '</td>
<td>' . $row["wantedName"]. "<br>"
. $row["servicesWantedTitle"]. '</td>
<td>' . $row["servicesWantedDescription"]. ' </td>
<td>' . $row["location"]. '</td>
</tr>';
}
You have duplicate field names: offeredcategory.categoryNameand wantedcategory.categoryName will both be retrieved $row['categoryName'] so only one will show up - categoryName is ambiguous but not rejected by MySQL because the SQL statement is clear and the problem is processing the results in PHP. Simple solution is:
offeredcategory.categoryName as offeredName
wantedcategory.categoryName as wantedName
and retrieve with $row['offeredName'] or $row['wantedName'] depending on what you actually want to display.
Complete SQL becomes:
SELECT customers.*, ads.*, categoriesselected.categoryselectedID, categoriesselected.offeredcategoryID, offeredcategory.categoryID, offeredcategory.categoryName as offeredName, categoriesselected.wantedcategoryID, wantedcategory.categoryID, wantedcategory.categoryName as wantedName
FROM customers
INNER JOIN ads ON ads.customerId = customers.customerID
INNER JOIN categoriesselected ON categoriesselected.adID = ads.adID
LEFT OUTER JOIN categories AS offeredcategory ON offeredcategory.categoryID = categoriesselected.offeredcategoryID
LEFT OUTER JOIN categories AS wantedcategory ON wantedcategory.categoryID = categoriesselected.wantedcategoryID";
I doing league table football and There is a profile of Team (Like : Team.php?team=XXX)
In this page I want to show, What position of TeamXXX in League Table
Page League Table
<?php
$number = 0;
$sql = "SELECT * FROM `leaguetable` WHERE `league` = 'leaguename' ORDER BY pts DESC";
$query = mysql_query($sql);
while($rs=mysql_fetch_assoc($query)){
$number++;
?>
<table>
<thead>
<tr>
<th>Position</th>
<th>Team</th>
<th>Points</th>
</tr>
</thead>
<tbody>
<td><?php echo $number; ?></td>
<td><?php echo $rs['team']; ?></td>
<td><?php echo $rs['pts']; ?></td>
</tbody>
</table>
<?php } ?>
Data in Table leaguetable
id team pts
In team.php I want to show position of TeamXXX
<?php
$getTeam = mysql_fetch_assoc(mysql_query("SELECT * FROM `leaguetable` WHERE `team`='"$_GET['team']"'");
?>
<table>
<thead>
<tr>
<th>Position</th>
<th>Team</th>
<th>Points</th>
</tr>
</thead>
<tbody>
<td>#########</td>
<td><? echo $getTeam['team']; ?></td>
<td><? echo $getTeam['pts']; ?></td>
</tbody>
</table>
How can I know what position of teamXXX in leaguetable?
Any help will be greatly appreciated. Thank you very much
query
select id, team, pts, rnk
from
(
select leag.id, leag.team, leag.pts,
#rnk := if(leag.pts = #lag, #rnk,
if(#lag := leag.pts, #rnk + 1, #rnk + 1)) as rnk
from leaguetable leag
cross join ( select #rnk := 0, #lag := null ) params
where league = 'FA Cup'
order by leag.pts desc
) rankings
where team = 'Chelsea'
;
example.php
<?php
/**
* Mysqli initial code
*
* User permissions of database
* Create, Alter and Index table, Create view, and Select, Insert, Update, Delete table data
*
* #package PhpFiddle
* #link http://phpfiddle.org
* #since 2012
*/
require_once "dBug!.php";
require "util/public_db_info.php";
$short_connect = new mysqli($host_name, $user_name, $pass_word, $database_name, $port);
if (mysqli_connect_errno())
{
die("Failed to connect to MySQL: " . mysqli_connect_error());
}
/*
$sql = "create table leaguetable"
. "("
. " id integer primary key not null,"
. " team varchar(33) not null,"
. " pts integer not null default 0"
. ");";
$result = $short_connect->query($sql);
if(!$result)
{
die("Create table failed : " . mysqli_error($short_connect));
}
$sql = "insert into leaguetable"
. "( id, team, pts )"
. "values"
. "( 1, 'Liverpool', 22 ),"
. "( 2, 'Arsenal', 29 ),"
. "( 3, 'Chelsea', 23 ),"
. "( 4, 'Tottenham', 23)";
$result = $short_connect->query($sql);
if(!$result)
{
die("insert failed : " . mysqli_error($short_connect));
}
*/
//get all tables in the database
//$sql = "SHOW TABLES";
//get column information from a table in the database
//$sql="SELECT COLUMN_KEY, COLUMN_NAME, COLUMN_TYPE FROM information_schema.COLUMNS WHERE TABLE_NAME = 'books'";
//SQL statement for a table in the database
$sql = "select id, team, pts, rnk "
. "from"
. "("
. "select leag.id, leag.team, leag.pts,"
. "#rnk := if(leag.pts = #lag, #rnk,"
. " if(#lag := leag.pts, #rnk + 1, #rnk + 1)) as rnk "
. "from leaguetable leag "
. "cross join ( select #rnk := 0, #lag := null ) params "
. " where league = 'FA Cup' "
. "order by leag.pts desc;"
. ") rankings "
. where team = 'Chelsea';";
//result is boolean for query other than SELECT, SHOW, DESCRIBE and EXPLAIN
$result = $short_connect->query($sql);
if (($result) && ($result->num_rows > 0))
{
echo "<table>" . "<thead>" . "<tr>" . "<th>Position</th>" . "<th>Team</th>" . "<th>Points</th>" . "</tr>" . "</thead>" . "<tbody>";
//convert query result into an associative array
echo "<tr><td>" . $row['rnk'] . "</td><td>" . $row['team'] . "</td><td>" . $row['pts'] . "</td></tr>";
echo "</tbody></table>";
}
else
{
die("select failed : " . mysqli_error($short_connect));
}
$short_connect->close();
?>
output
<table>
<thead>
<tr>
<th>Position</th>
<th>Team</th>
<th>Points</th>
</tr>
</thead>
<tbody>
<tr>
<td>2</td>
<td>Chelsea</td>
<td>23</td>
</tr>
</tbody>
</table>
sqlfiddle
Hope this will help
$number = 0;
$points=0;
$sql = "SELECT * FROM `leaguetable` WHERE `league` = 'leaguename' ORDER BY pts DESC";
$query = mysql_query($sql);
while($rs=mysql_fetch_assoc($query)){
if($points!=$rs['pts'])
$number++;
if($rs['team']==$_GET['team']){
if($points==$rs['pts'])
$position=$number-1;
else
$position=$number;
}
$poins=$rs['pts'];
}
If you don't mind using two queries (I wouldn't mind it), it's pretty easy: Just count how many teams have more points, and add one (so that if three teams are tied in second position, they all get position 2).
$result = mysql_query("SELECT count(*)+1 AS POSTN FROM leaguetable WHERE
league = 'leaguename' AND pts > $points");
$row = mysql_fetch_assoc($result);
$position = $row["POSTN"];
Doing it in one query is a bit messier, since you need to embed this query in your original one:
"SELECT *, (SELECT count(*)+1 FROM leaguetable table2
WHERE league = 'leaguename' AND table2.pts > leaguetable.pts) AS POSTN
FROM leaguetable WHERE team = '$currentteam'"
But why are you using the mysql_* API for new code? Haven't you noticed all the dire warnings in pink boxes in the documentation? Do yourself a favor and switch to mysqli today, starting with this program.
Also: Never just inject $_GET[param] into your query string! You're giving yourself an SQL injection attack waiting to happen... and brittle, error-prone code until then.
i'm trying to find a solution, i'm trying to get a data from different tables using same id. Here is my code
"SELECT * FROM menucat LEFT JOIN vmenutab ON menucat.cat_id = vmenutab.menu_id";
I need to create sections, and fill them later with some content, table menucat is parent table with sections, vmenutab is child table with content.
But i have a problem, it doesn't show up correctly. It should be like this:
Section1
Link1
Link2
But it shows up like this:
Section1
Link1
Section1
Link2
I've been using search, GROUP BY and DISTINCT didn't worked.
tables:
menucat:
cat_id menu_cat_est menu_cat_ru menu_cat_en
vmenutab:
id (unique link id) menu_id (id to related section) menu_name_est menu_name_ru menu_name_en
menu_cat_xxx and menu_name_xxx are different languages data
PHP Code
<?php
$target = "SELECT * FROM menucat LEFT JOIN vmenutab ON menucat.cat_id = vmenutab.menu_id";
$mq = mysql_query($target);
while ($row = mysql_fetch_array($mq)) {
$menu_cat_est = $row['menu_cat_est'];
$menu_cat_ru = $row['menu_cat_ru'];
$menu_cat_en = $row['menu_cat_en'];
$menu_name_est = $row['menu_name_est'];
$menu_name_ru = $row['menu_name_ru'];
$menu_name_en = $row['menu_name_en'];
$cat_id = $row['cat_id'];
$id = $row['id'];
echo '<tr>
<td>' . $menu_cat_est . ''.$menu_name_est.'</td>
<td>' . $menu_cat_ru . ''.$menu_name_ru.'</td>
<td>' . $menu_cat_en . ''.$menu_name_en.'</td>
<td scope="col"><center><img src="style/stylesheet/images/edit.png"></center></td>
<td scope="col"><center><img src="style/stylesheet/images/delete.png"></center></td>
<td scope="col"><center>Добавить</center></td>
</tr>';
}
?>
Sorry for my english. Best Regards.
EDIT: Added entire PHP Code.
EDIT #2: Added table rows.
an example as i don't know your db data. also sort db by cat id
' . $menu_cat_xxx . ''.$menu_name_xxx.' its a bit confusing
$target = "SELECT * FROM menucat LEFT JOIN vmenutab ON menucat.cat_id = vmenutab.menu_id" order by menucat.cat_id;
$mq = mysql_query($target);
while ($row = mysql_fetch_array($mq)) {
$menu_cat_est = $row['menu_cat_est'];
$menu_cat_ru = $row['menu_cat_ru'];
$menu_cat_en = $row['menu_cat_en'];
$menu_name_est = $row['menu_name_est'];
$menu_name_ru = $row['menu_name_ru'];
$menu_name_en = $row['menu_name_en'];
$cat_id = $row['cat_id'];
$id = $row['id'];
if(!$nocat[$cat_id]){ $nocat[$cat_id] = $cat_id; $section='<tr><td colspan="6"> section' . $cat_id . '</td></tr>
';}else{$section='';} // customise as i need sleep
echo $section.
'<tr>
<td>' . $menu_cat_est . ''.$menu_name_est.'</td>
<td>' . $menu_cat_ru . ''.$menu_name_ru.'</td>
<td>' . $menu_cat_en . ''.$menu_name_en.'</td>
<td scope="col"><center><img src="style/stylesheet/images/edit.png"></center></td>
<td scope="col"><center><img src="style/stylesheet/images/delete.png"></center></td>
<td scope="col"><center>Добавить</center></td>
';
}
I have the following markup which shows a list of categories and subcategories:
<table border="0" width="100%" cellspacing="0" cellpadding="2">
<tr class="dataTableHeadingRow">
<td class="dataTableHeadingContent"><?php echo TABLE_HEADING_PRODUCTS; ?></td>
<td class="dataTableHeadingContent" align="right"><?php echo TABLE_HEADING_TOTAL_WEIGHT; ?> </td>
</tr>
<?php
function category_list( $category_parent_id = 0 )
{
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order from ' . TABLE_CATEGORIES . ' c, ' . TABLE_CATEGORIES_DESCRIPTION . ' cd where c.categories_id = cd.categories_id AND c.parent_id='.$category_parent_id;
$res = tep_db_query( $sql );
$cats = array();
while ( $cat = tep_db_fetch_array( $res ) )
{
$cats[] = $cat;
}
if (count($cats) == 0)
{
return '';
}
$list_items = array();
foreach ( $cats as $cat )
{
$list_items[] = '<tr class="dataTableRow"><td class="dataTableContent">';
if($category_parent_id != 0) $list_items[] = ' ';
if($category_parent_id == 0 )$list_items[] = '<b>';
$list_items[] = $cat['categories_name'];
if($category_parent_id == 0) $list_items[] = '</b>';
$list_items[] = '</td><td class="dataTableContent">';
$list_items[] = category_list( $cat['categories_id'] );
$list_items[] = '</td></tr>';
}
$list_items[] = '';
return implode( '', $list_items );
}
echo category_list();
?>
</table>
Each category is show in bold and the sub category is shown slightly indented to the right. I need to show the products available in each of the subcategory's. I tried adding the needed product fields to the sql query, but it didn't respond. The fields I need to add to search for the products are: products_id, products_name, these are from the table TABLE_PRODUCTS_DESCRIPTION, and to sort it their categories, there is another table called TABLE_PRODUCTS_TO_CATEGORIES, which has the fields products_id and categories_id.
How would I go about doing this?
It looks like you are using osCommerce or one of its forks and you want to display the amount of products for each category.
If you have only two levels of categories that's ok to do, if your category tree goes deeper, be warned that this is a real performance killer as building the category-tree in osCommerce is done, let's say, not really performance optimized, especially for complex tree structures.
The straight forward way is, to count the entries of the TABLE_PRODUCTS_TO_CATEGORIES table where the column categories_id holds the current category id:
$query = 'SELECT COUNT(*) FROM `'.TABLE_PRODUCTS_TO_CATEGORIES.'` WHERE `categories_id` = "'.$cat['categories_id'].'"';
Fetch the result and you have the count.
With this approach though you will only get the count of products directly in tnis category, not the count of products which reside in children categories.
You might also have a look on includes/boxes/categories.php as this is already built in in osC - the methods tep_show_category() and the herein called tep_count_products_in_category() might be usable for your purpose so no need to write it yourself.
I don't really like the from thing in the query for joining 2 tables. I have changed the query the way I prefer. You can change it to the from way if you wish.
$sql = 'select cd.categories_name,c.categories_id, c.parent_id, c.sort_order, pd.products_id, pd.products_name
from ' . TABLE_CATEGORIES . ' c
inner join ' . TABLE_CATEGORIES_DESCRIPTION . ' cd on c.categories_id = cd.categories_id
inner join '. TABLE_PRODUCTS_TO_CATEGORIES .' pc on pc.categories_id=c.categories_id
inner join ' . TABLE_PRODUCTS_DESCRIPTION . ' pd on pd.products_id=pc.products_id
where c.parent_id='.$category_parent_id;
My database table have 5 columns: 'id', 'date_visited', 'page_title', 'ip' and 'total_views'.
I am not able to display ORDER BY 'date_visited'.
My PHP Query is:
<?php
[...]
$query = "SELECT *,count(*) FROM table WHERE ip GROUP BY page_title";
$result = mysqli_query($link,$query) or die(mysqli_error($link). "Q=".$query);
if(!$result == 0) {
while ($row = mysqli_fetch_array($result)) {
$dataList_br .= '<tr>
<td>' .$row['date_visited']. '</td>
<td>' .$row['page_title']. '</td>
<td>' .$row['count(*)']. '</td>
</tr>';
}
} else {
$dataList_br .= '<p class="warning">No data found in database.</p>';
}
?>
When it outputs, it displays [date][page title] and [total views].
Please someone help me, how do I display last date from the query, instead now it displays the very first day the page was visited.
Thank you.
MySQL is lenient about the contents of the GROUP BY and will return a row for the group somewhat arbitrarily if columns aren't in the GROUP BY but are SELECTed. In your case, it just gave you the first row (lowest date) for each group.
Get the page_name of the row with the MAX(date_visited) per group and join that against the main table to pull in the remaining columns from the main table.
SELECT
table.id,
table.ip,
table.total_views,
maxdates.date_visited,
maxdates.page_name,
maxdates.thecount
FROM
table
JOIN (
/* Subquery returns the aggregates to join against
the main table so other columns can be pulled in */
SELECT
page_title,
MAX(date_visited) AS maxdate,
COUNT(*) AS thecount
FROM table
GROUP BY page_title
) maxdates
ON table.page_name = maxdates.page_name
AND table.date_visited = maxdates.maxdate
You want to use ORDER BY. Like so:
$query = "SELECT *, count(*)
FROM table
WHERE ip
GROUP BY page_title
ORDER BY date_visited ASC";
Try this whit "ORDER BY":
$query = "SELECT date_visited, page_title,count(*) FROM table WHERE ip ORDER BY page_title ASC";
$result = mysqli_query($link,$query) or die(mysqli_error($link). "Q=".$query);
if(!$result == 0) {
while ($row = mysqli_fetch_array($result)) {
$dataList_br .= '<tr>
<td>' .$row['date_visited']. '</td>
<td>' .$row['page_title']. '</td>
<td>' .$row['count(*)']. '</td>
</tr>';
}
} else {
$dataList_br .= '<p class="warning">No data found in database.</p>';
}