Get users which are not stated in the query - php

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 ...

Related

Select - Rows for Columns possible?

i have this select:
SELECT
a.`cod_oportunidade`,
b.nome nome_cliente,
c.descricao estado,
d.descricao cidade,
e.nome nome_funcionario_criou,
f.nome nome_funcionario_resp,
i.`descricao`,
h.`valor`
FROM
oportunidades_clientes a
LEFT OUTER JOIN empresas_clientes b
ON b.cod_cliente = a.cod_cliente
LEFT OUTER JOIN sistema_estados c
ON c.cod_estado = b.cod_estado
LEFT OUTER JOIN sistema_cidades d
ON d.cod_cidade = b.cod_cidade
LEFT OUTER JOIN empresas_funcionario e
ON e.cod_funcionario = a.cod_funcionario_criou
LEFT OUTER JOIN empresas_funcionario f
ON f.cod_funcionario = a.cod_funcionario_resp
JOIN formulario_valor h
ON h.`cod_oportunidade` = a.`cod_oportunidade`
JOIN formulario_campo i
ON i.`cod_campo` = h.`cod_campo`
WHERE 1 = 1
AND a.`cod_oportunidade` = 3
The result is therefore:
My question is... Need to inves need to stay several lines that the result is only one line. The data in the column "descricao" must be as columns ...
The implode() function will separate an array (columns from a database) with whatever character you prefer, in your case a pipe:
$mysqli = mysqli_connect("host","user","pass","db");
$result = mysqli_query($mysqli, "SELECT ...");
while ($row = mysqli_fetch_array($result)) {
echo implode(" | ", $row) . '<br />';
}

php mysql while loop query optimization

I have php/mysql script running which is like this:
$sql = "select a.column1 from table1 a";
$query = mysql_query($sql);
while ($fec = mysql_fetch_assoc($query)) {
$sub1 = "select column1,column2 from subtable1 where id=" . $fec['a.column1'];
$subquery1 = mysql_query($sub1);
while ($subfec1 = mysql_fetch_assoc($subquery1)) {
//all data .....
}
$sub1 = "select column1,column2 from subtable2 where id=" . $fec['a.column1'];
$subquery2 = mysql_query($sub2);
while ($subfec2 = mysql_fetch_assoc($subquery2)) {
//all data .....
}
$sub2 = "select column1,column2 from subtable3 where id=" . $fec['a.column1'];
$subquery3 = mysql_query($sub3);
while ($subfec3 = mysql_fetch_assoc($subquery3)) {
//all data .....
}
}
Now I've many many many records in table1, subtable1, subtable2 and subtable3. And problem is that it takes around 7 hours to display the results. Moreover the CPU Usage is 100%
Please suggest the optimization tips to overcome this issue.
Use a single query to get all records
SELECT
a.column1,
s.column1,
s.column2,
s2.column1,
s2.column2,
s3.column1,
s3.column2
FROM table1 a
LEFT JOIN subtable1 s ON s.id = a.column1
LEFT JOIN subtable2 s2 ON s.id = a.column1
LEFT JOIN subtable3 s3 ON s.id = a.column1
Here
$sql="
SELECT
a.column1 acolumn1,
s.column1 scolumn1,
s.column2 scolumn2,
s2.column1 s2column1,
s2.column2 s2column2,
s3.column1 s3column1,
s3.column2 s3column2
FROM table1 a
LEFT JOIN subtable1 s ON s.id = a.column1
LEFT JOIN subtable2 s2 ON s.id = a.column1
LEFT JOIN subtable3 s3 ON s.id = a.column1";
$query=mysql_query($sql);
while ($fec=mysql_fetch_assoc($query)) {
// display any info here
}
Use aliases for accessing different table columns

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}'";
}

Convert sql php script to coldfusion

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>

php code to calculated unread posts in phpbb directly from database

I'm trying to retrieve a specific users unread posts total from a phpbb3 database directly. I'm using ezsql to make my life easier, and I've written the following code based on the following post: https://www.phpbb.com/community/viewtopic.php?f=46&t=2107403#p12881167
$unreadposts always seems to return a number thats higher than the actual number of unread posts. I've been working on this the last 12 hours and its tearing my hair out :)
Any help or suggestions would be most appreciated!
// Step 1: get all topics the user has access to. Assuming all of them are unread until we prove otherwise
$usertopicsallowed = $forumdb->get_results("SELECT DISTINCT t.topic_id, t.forum_id, t.topic_last_post_time FROM $forumdbname.phpbb_users u
INNER JOIN $forumdbname.phpbb_user_group ug ON u.user_id = ug.user_id
INNER JOIN $forumdbname.phpbb_groups g ON g.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_acl_groups acl ON acl.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_forums f ON f.forum_id = acl.forum_id
INNER JOIN $forumdbname.phpbb_topics t ON f.forum_id = t.forum_id
WHERE u.user_id = " . $forumuserid . ";");
$usertopicsallowedcnt = count($usertopicsallowed);
// Step 2: Return any topics for this user in topics_track
$usertopicstrack = $forumdb->get_results("SELECT topic_id, mark_time FROM phpbb_topics_track WHERE user_id = " . $forumuserid . " ;");
if (!empty($usertopicsallowed))
{
foreach($usertopicsallowed as $key => $usertopicallowed)
{
if (!empty($usertopicstrack))
{
foreach($usertopicstrack as $key2 => $usertopictrack)
{
if ($usertopicsallowed[$key]->topic_id == $usertopicstrack[$key2]->topic_id)
{
if ($usertopicsallowed[$key]->topic_last_post_time < $usertopicstrack[$key2]->mark_time)
{
unset($usertopicsallowed[$key]);
}
}
}
}
}
}
$usertopicsallowed2 = array_values($usertopicsallowed);
$usertopicsallowed2cnt = count($usertopicsallowed2);
// Step 3a: eturn any topics for this user in forums_track
$userforumstrack = $forumdb->get_results("SELECT forum_id, mark_time FROM phpbb_forums_track WHERE user_id = " . $forumuserid . ";");
// Step 3b: remove all topics before the forum tracks lastmark time
if (!empty($usertopicsallowed2))
{
foreach($usertopicsallowed2 as $key => $usertopicsallow2)
{
if (!empty($userforumstrack))
{
foreach($userforumstrack as $key2 => $userforumtrack)
{
if ($usertopicsallowed2[$key]->forum_id == $userforumstrack[$key2]->forum_id)
{
if ($usertopicsallowed2[$key]->topic_last_post_time < $userforumstrack[$key2]->mark_time)
{
unset($usertopicsallowed2[$key]);
}
}
}
}
}
}
$usertopicsallowed3 = array_values($usertopicsallowed2);
$usertopicsallowed3cnt = count($usertopicsallowed3);
// Step 4: remove all topics before the user's lastmark time
if (!empty($usertopicsallowed3))
{
foreach($usertopicsallowed3 as $key => $usertopicsallow3)
{
if ($usertopicsallowed3[$key]->topic_last_post_time < $forumuserlastmark)
{
unset($usertopicsallowed3[$key]);
}
}
}
$usertopicsallowed4 = array_values($usertopicsallowed3);
$usertopicsallowed4cnt = count($usertopicsallowed4);
$unreadposts = count($usertopicsallowed4);
OK so as I said in my comment above, after 12 hours failing to get this to work I found an answer within 15 minutes of posting here! Noting this reply so maybe it will help someone else in the future, and I'll also reply on the link as well.
This link gives the answer (https://www.phpbb.com/community/viewtopic.php?f=46&t=2092813#p12800435) but doesn't allow for permissions, so you need to add the code I wrote below in addition. The full code is therefore:
// Step 1: get all topics the user has access to. Assuing all of them are unread until we prove otherwise
$usertopicsallowed = $forumdb->get_results("SELECT DISTINCT t.topic_id, t.forum_id, t.topic_last_post_time FROM $forumdbname.phpbb_users u
INNER JOIN $forumdbname.phpbb_user_group ug ON u.user_id = ug.user_id
INNER JOIN $forumdbname.phpbb_groups g ON g.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_acl_groups acl ON acl.group_id = ug.group_id
INNER JOIN $forumdbname.phpbb_forums f ON f.forum_id = acl.forum_id
INNER JOIN $forumdbname.phpbb_topics t ON f.forum_id = t.forum_id
WHERE u.user_id = " . $forumuserid . ";");
// Step 2: Calculate unread posts in all forums (regardless of permissions)
$phpbbv2 = $forumdb->get_results("SELECT t.topic_id, t.topic_last_post_time, tt.mark_time as topic_mark_time, ft.mark_time as forum_mark_time FROM (phpbb_topics t)
LEFT JOIN phpbb_topics_track tt ON (tt.user_id = " . $forumuserid . " AND t.topic_id = tt.topic_id)
LEFT JOIN phpbb_forums_track ft ON (ft.user_id = " . $forumuserid . " AND t.forum_id = ft.forum_id)
WHERE ( (tt.mark_time IS NOT NULL AND t.topic_last_post_time > tt.mark_time)
OR (tt.mark_time IS NULL AND ft.mark_time IS NOT NULL AND t.topic_last_post_time > ft.mark_time)
OR (tt.mark_time IS NULL AND ft.mark_time IS NULL AND t.topic_last_post_time > " . $forumuserlastmark . ") ) AND t.topic_moved_id = 0 AND t.topic_approved = 1 ORDER BY t.topic_last_post_time DESC;");
// Step 3: Loop through step 2 and only increment the counter for every topic the user has permission to view
$unreadcounter=0;
if (!empty($phpbbv2))
{
foreach($phpbbv2 as $key => $phpbbv2a)
{
if (!empty($usertopicsallowed))
{
foreach($usertopicsallowed as $key2 => $usertopicallowed)
{
if ($phpbbv2[$key]->topic_id == $usertopicsallowed[$key2]->topic_id)
{
$unreadcounter++;
}
}
}
}
}
$unreadpost=$unreadcounter;
I'm sure it could be better, I'm not the most experienced in php but its working for me.

Categories