$sql="SELECT advertiser_name from broker_blocked_advertisers where pline=".$pLine." AND bid=".$cNr;
$result=mysqli_query($conn,$sql);
if(mysqli_num_rows($result)>0){
while($row=mysqli_fetch_array($result)){
$s=trim($row['advertiser_name']);
$sql2= "SELECT clientid from rv_clients where clientname='{$s}'";
$result2=mysqli_query($dbc,$sql2);
while($row2=mysqli_fetch_array($result2)){
$sql3= "SELECT campaignid from rv_campaigns where clientid=".$row2['clientid'];
$result3=mysqli_query($dbc,$sql3);
while($row3=mysqli_fetch_array($result3)){
$sql4= "SELECT bannerid from rv_banners where campaignid=".$row3['campaignid'];
$result4=mysqli_query($dbc,$sql4);
while($row4=mysqli_fetch_array($result4)){
$block_adr[]= $row4['bannerid'];
}
}
}
}
}
Anybody please suggest me to simplify the above code in a single query???.
The above code is really a wrong approach i think, please help how to short it out?.
Code description: Here i get one value from a sql table and by using that value i step forward to another query and so on.
Thanks in advance
Revised query and script:-
$sql = "SELECT d.bannerid
FROM broker_blocked_advertisers a
INNER JOIN rv_clients b ON a.advertiser_name = b.clientname
INNER JOIN rv_campaigns c ON b.clientid = c.clientid
INNER JOIN rv_banners d ON c.campaignid = d.ampaignid
WHERE a.pline=".$pLine." AND a.bid=".$cNr;
$result=mysqli_query($dbc,$sql);
while($row=mysqli_fetch_array($result))
{
$block_adr[]= $row['bannerid'];
}
This is the dreaded (n+1) latency death, four times over.
Every iteration through a loop is another network roundtrip. That's going to kill your performance.
Think "join". Bring all the data back in one round trip and sort it out on the client side.
Here's a simplified example:
select *
from campaign
join banner
on campaign.id = banner.campaign_id
That saves looping over campaigns.
All in one query
$sql="SELECT
bann.bannerid,camp.campaignid,c.clientid,b.advertiser_name as advname
from
broker_blocked_advertisers as b,
rv_clients as c,
rv_campaigns as camp,
rv_banners as bann
where b.pline=".$pLine."
AND bid=".$cNr."
AND c.clientname=advname.advertisername
AND camp.clientid=c.clientid
AND bann.campaign_id=camp.campaig_id"
YOU CAN USE A SINGLE QUERY LIKE THIS:
SELECT bannerid from rv_banners where campaignid=
(
SELECT campaignid from rv_campaigns where clientid=
(
SELECT clientid from rv_clients where clientname=
(
SELECT advertiser_name from broker_blocked_advertisers where pline=".$pLine."
AND bid=".$cNr;
)
)
);
SELECT "bannerId" FROM rv_banners A, rv_campaigns B, rv_clients C, broker_blocked_advertisers D
WHERE A.campaignid = B.campaignid AND B.clientid = C.clientname AND C.clientname = D.advertisername AND D.pline = ".$pline." AND D.bid = ".$cNr;
Related
I first search all questions info. from "question" table including title, content, user etc.
the Code:
$sql = "select * FROM question where id>0 ORDER BY id ASC";
$result1 = mysql_query($sql);
$res=Array();
And then I want to search the user's point from "user" table. So I must search point for each user in each row from the result1
The Code:
while($rows=mysql_fetch_assoc($result1))
{
$res[]=$rows;
$user = $rows['user'];
$sql2 = "select point from user where name='$user'";
$result2 = mysql_query($sql2);
}
My problem is how to combine all the users' point(result2) with the questions info.(result1) together so that I can return a json for each row.
Use left join, as my understanding this work for you
$sql = "SELECT q.*, u.point AS point FROM question AS q LEFT JOIN user AS u ON q.user = u.name WHERE q.id > 0 ORDER BY q.id ASC";
$result = mysql_query($sql);
It's better go with the joins here i am giving you the query.i hope it may helps you
select * from question q,user u where q.id>0 ORDER BY id ASC
try something like this:using left join
select question.*,user.point FROM question left join user on user.name= question.name where id>0 ORDER BY id ASC
Lets say i have a list full of phones.
It's easy to print all the phones out in a unordered list like:
$get_phones = $mysqli->query("
SELECT
a.id,
b.phone_id,
a.phonename AS pname,
b.modelname AS mname,
FROM phone_brands
a LEFT OUTER JOIN phone_models b
ON a.id = b.phone_id");
while($phones = $get_phones->fetch_assoc()){
echo $phones['pname'] . $phones['mname'];}
But how can i make the list more readable by sorting all the models and phones like:
Iphone
3G
3GS
4G
Nokia
Lumia 1020
Lumia 925
Lumia 520
My guess is that i should do something like:
if($phones['pname'] == $phones['pname']{}
But i don't know if i'm far away here? Any help would be appreciated :)
Well ofcourse you could order the query by mname:
$get_phones = $mysqli->query("
SELECT
a.id,
b.phone_id,
a.phonename AS pname,
b.modelname AS mname,
FROM phone_brands
a LEFT OUTER JOIN phone_models b
ON a.id = b.phone_id
ORDER BY mname");
And then in php do something like:
$currentModel = "";
while($phones = $get_phones->fetch_assoc()){
if($currentModel != $phones['mname']){
echo $phones['mname'].'<br/>';
$currentModel = $phones['mname'];
}
echo $phones['pname'];
}
Sorting on the database level is much faster and at the end, the result is the same. You can just read it in a PHP array and have it sorted.
$get_phones = $mysqli->query("
SELECT
a.id,
b.phone_id,
a.phonename AS pname,
b.modelname AS mname,
FROM phone_brands
a LEFT OUTER JOIN phone_models b
ON a.id = b.phone_id
order by pname, mname");
SELECT
a.id,
b.phone_id,
a.phonename AS pname,
b.modelname AS mname,
FROM phone_brands AS a
LEFT OUTER JOIN phone_models AS b
ON a.id = b.phone_id
ORDER BY pname, mname DESC
That should do the job from what your question asks?
[edit]
I need to improve the code, i'm thinking using something like a foreach so it's more useable later than just order by :P – Simon Duun
Going on that comment, you could still use the order by in the query but do something like:
$phone_array = array();
while($phones = $get_phones->fetch_assoc()){
$phone_array[$phones['pname']] = $phones['pname'] . $phones['mname'];
}
ksort($phone_array);
foreach($phone_array as $phone_pname => $phone_value){
echo $phone_pname . ' -> ' . $phone_value . "\r\n";
}
I am creating a dashboard to keep me updated on call agent status.an agent will have multiple records in the log. I need to pull the most recent status from the agent log. The only way I have found is to query the agent table to pull the agents with status changes made today and then query the agent log table to pull the most recent status.
is there a way to combine the two queries.? Here are my queries
$sql_get_agents = "SELECT id FROM agent WHERE lastchange LIKE '{$today}%'";
if($dta = mysql_query($sql_get_agents)){
while($agent = mysql_fetch_assoc($dta)){
$curr_agent[] = $agent;
}
foreach($curr_agent as $agents_online){
$get_status_sql = "SELECT a.firstname,a.lastname,al.agentid,al.agent_statusid,s.id as statusid,s.status,MAX(al.datetime) as datetime FROM agent_log al
INNER JOIN agent a ON al.agentid = a.id
INNER JOIN agent_status s ON a.agent_statusid = s.id
WHERE al.agentid = '{$agents_online['id']}'";
if($dta2 = mysql_query($get_status_sql)){
while($agent_status = mysql_fetch_assoc($dta2)){
$curr_status[] = $agent_status;
}
}
}//end for each
return $curr_status;
}//end if
Why don't you join the 2 queries into one adding the WHERE lastchange LIKE '{$today}%' condition in the second query?
Using the IN clause should work :
"SELECT a.firstname,a.lastname,al.agentid,al.agent_statusid,s.id as statusid,s.status,MAX(al.datetime) as datetime FROM agent_log al
INNER JOIN agent a ON al.agentid = a.id
INNER JOIN agent_status s ON a.agent_statusid = s.id
WHERE al.agentid IN (SELECT id FROM agent WHERE lastchange LIKE '{$today}%');
You were close with what you have. This will get rid of the need to do both queries, or query in a loop.
edit: adding example code to loop over the results as well.
edit2: changed query.
$query = "SELECT
a.firstname,
a.lastname,
al.agentid,
al.agent_statusid,
s.id as statusid,
s.status,
MAX(al.datetime) as datetime
FROM agent a
LEFT JOIN agent_log al ON al.agentid = a.id
LEFT JOIN agent_status s ON a.agent_statusid = s.id
WHERE a.lastchange LIKE '{$today}%'";
$status = array();
$results = mysql_query( $query );
while( $agent = mysql_fetch_assoc( $results ) )
$status[] = $agent;
print_r( $status );
i have this piece of code that selects all users from the table and another sql statement that counts the number of records for every user. the problem I'm facing is that i have a sql in a foreach loop which is not good for performance but i wasn't able to combine both of them in one statement. any advise?
$query = $db->getAll("SELECT * FROM users");
foreach($query as $v){
$tpl->setCurrentBlock('useri');
$query2 = $db->numRows("SELECT * FROM signups AS s INNER JOIN users AS u ON s.userid=u.id WHERE u.id={$v['id']}");
$tpl->setVariable('total',$query2);
$tpl->setVariable($v);
$tpl->parseCurrentBlock();
}
Try this query against your DB:
SELECT u.id, COUNT(s.*)
FROM users u
LEFT JOIN signups s ON s.userid = u.id
GROUP BY u.id
I hope I got it right. I have no SQL DB to test it right here. Important: You have to group by each field you select that is no aggregate.
Edit:
If it is not fast enough yet, an index on signups.userid may help. This is hypothetic, however, so you should check the Execution Plan your query engine generates.
$query = $db->getAll("
SELECT u.id, u.name, COUNT(*) total
FROM signups AS s RIGHT JOIN users AS u ON s.userid=u.id
GROUP BY u.id, u.name
ORDER BY u.name
");
foreach($query as $v){
$tpl->setCurrentBlock('useri');
$tpl->setVariable('total', $query['total']);
// ...
$tpl->parseCurrentBlock();
}
If I understand good your problem, initialize variable and in loop increase it.
int i;
foreach($query as $v){
$tpl->setCurrentBlock('useri');
$query2 = $db->numRows("SELECT * FROM signups AS s INNER JOIN users AS u ON s.userid=u.id WHERE u.id={$v['id']}");
$tpl->setVariable('total',$query2);
$tpl->setVariable($v);
$tpl->parseCurrentBlock();
i++;
}
Hey guys need some more help
I have 3 tables USERS, PROFILEINTERESTS and INTERESTS
profile interests has the two foreign keys which link users and interests, they are just done by ID.
I have this so far
$statement = "SELECT
InterestID
FROM
`ProfileInterests`
WHERE
userID = '$profile'";
Now I want it so that it selects from Interests where what it gets from that query is the result.
So say that gives out 3 numbers
1
3
4
I want it to search the Interests table where ID is = to those...I just don't know how to physically write it in PHP...
Please help.
Using a JOIN:
Best option if you need values from the PROFILEINTERESTS table.
SELECT DISTINCT i.*
FROM INTERESTS i
JOIN PROFILEINTERESTS pi ON pi.interests_id = i.interests_id
WHERE pi.userid = $profileid
Using EXISTS:
SELECT i.*
FROM INTERESTS i
WHERE EXISTS (SELECT NULL
FROM PROFILEINTERESTS pi
WHERE pi.interests_id = i.interests_id
AND pi.userid = $profileid)
Using IN:
SELECT i.*
FROM INTERESTS i
WHERE i.interests_id IN (SELECT pi.interests_id
FROM PROFILEINTERESTS pi
WHERE pi.userid = $profileid)
You are on the right track, lets say you execute the query above using this PHP code:
$statement = mysql_query("SELECT InterestID FROM `ProfileInterests`
WHERE userID = '$profile'");
Then you can use a PHP loop to dynamically generate an SQL statement that will pull the desired IDs from a second table. So, for example, continuing the code above:
$SQL = "";
while ($statementLoop = mysql_fetch_assoc($statement)) {
//Note the extra space on the end of the query
$SQL .= "`id` = '{$statementLoop['InterestID']}' OR ";
}
//Trim the " OR " off the end of the query
$SQL = rtrim($SQL, " OR ");
//Now run the dynamic SQL, using the query generated above
$query = mysql_query("SELECT * FROM `table2` WHERE {$SQL}")
I haven't tested the code, but it should work. So, this code will generate SQL like this:
SELECT * FROM `table2` WHERE `id` = '1' OR `id` = '3' OR `id` = '4'
Hope that helps,
spryno724
Most likely you want to join the tables
select
i.Name
from
ProfileInterests p
inner join
interests i
on
p.interestid = i.interestid
where
p.userid = 1