I want to select a row that exist in the images table but not in the images_viewed table. They both share the same name.
This is the code I am using. it works, but it making my website very slow.
$next = $mysqli->query("SELECT `name` FROM `images` WHERE `name` NOT IN (SELECT `name` FROM `images_viewed` WHERE `ip` = '$ip') ORDER BY RAND() LIMIT 1");
if($next->num_rows == 1){
$fetch_next = $next->fetch_assoc();
$next_name = $fetch_next['name'];
}
how can I fix this code? is there a better select statement that I can use?
Try:
SELECT images.name FROM images
LEFT OUTER JOIN images_viewed
ON images.name = images_viewed.name
WHERE images_viewed.ANY_OTHER_FIELD IS NULL AND images_views.ip = {$ip}
Related
I am currently trying to get data from my table (mostKills by Weapon in a table with over 300 kills). Initially I did a normal query
$q = $mysql->query("SELECT * FROM `kills`") or die($mysql->error);
but when I tried to
$query2 = $mysql->query("SELECT `killerID`, COUNT(`killerID`) AS tot_kills FROM `kills` WHERE `killText` LIKE '%$gun%' GROUP BY `killerID` ORDER BY `tot_kills` DESC;") or die($mysql->error);
$kData = $query2->fetch_assoc();
$query3 = $mysql->query("SELECT `Username` FROM `players` WHERE `ID` = '" . $kData['killerID'] . "'") or die($mysql->error);
$uData = $query3->fetch_assoc();
$array[$gun]['Kills']++;
$array[$gun]['Gun'] = $gun;
$array[$gun]['BestKiller'] = $uData['Username'];
$array[$gun]['killAmount'] = $kData['tot_kills'];
function sortByKills($a, $b) {
return $b['Kills'] - $a['Kills'];
}
usort($array, 'sortByKills');
foreach($array as $i => $value)
{
// table here
}
I had to do it in a while loop, which caused there to be around 600 queries, and that is obviously not acceptable. Do you have any tips on how I can optimize this, or even turn this into a single query?
I heared JOIN is good for this, but I don't know much about it, and was wondering if you guys could help me
Try this...
I added a inner join and added a username to your select clause. The MIN() is just a way to include the username column in the select and will not have an impact on you result as long as you have just 1 username for every Killerid
SELECT `killerID`
, COUNT(`killerID`) AS tot_kills
, MIN(`Username`) AS username
FROM `kills`
INNER JOIN `players`
ON `players`.`id` = `kills`.`killerid`
WHERE `killText` LIKE '%$gun%'
GROUP BY `killerID`
ORDER BY `tot_kills` DESC
SELECT kills.killerID, count(kills.killerID) as killTotal, players.Username
FROM kills, players
WHERE kills.killText
LIKE '%$gun%'
AND players.ID` = kills.killerID
GROUP BY kills.killerID
ORDER BY kills.tot_kills DESC
Here is a good place to learn some more about joins.
http://www.sitepoint.com/understanding-sql-joins-mysql-database/
The best way is to have your own knowledge so you can be able to tune up your select queries.
Also put more indexes to your DB, and try to search and join by index.
What I am trying to do is to get all of the users with the right conditions
so I'm building with a foreach statment a sub_queries to make it work.
the problem is that I got 100,000+ records in the Database.
and this kind of query takes forever to run.
I know I'm not doing it in the best way but I also tried left joins, which was really slow too..
this is the function I'm using:
public function get_affected_users_by_conditions($conditions, $mobile_type)
{
// Basic Query
// Selecting all of the users from `enswitch_mobile users` table
// The total and the `users` with the conditions
$sql = "SELECT COUNT(*) AS `users`,
(SELECT COUNT(*) FROM `enswitch_mobile_users`) AS `total`
FROM
`enswitch_mobile_users` AS `musers`
WHERE
`musers`.`phone_type` = :mobile_type";
$value_counter = 0;
$values = array();
// This is the foreach loop I was talking about
// I am looping all the conditons.
// and when theres a value i'm adding it as a subquery.
foreach($conditions as $cnd) {
switch ($cnd['condition']) {
// REALLY SLOW SUB-QUERY:
case 'talked_atleast':
$value_counter++;
// Here I'm trying to CUT the query by users who talked atleast $value seconds
$sql .= " AND (SELECT SUM(TIME_TO_SEC(TIMEDIFF(`finished_call`,`start_call`))) FROM `enswitch_calls` WHERE `user_id` = `musers`.`id`) >= :value".$value_counter;
$values[$value_counter] = $cnd['value'];
break;
// REALLY SLOW SUB-QUERY:
case 'purchase_atleast':
// Here I am trying to CUT the users by subquery who check if the users has bought at least $value times
$value_counter++;
$sql .= " AND (SELECT COUNT(*) FROM (SELECT user_id FROM enswitch_new_iphone_purchases
UNION
SELECT user_id FROM enswitch_new_android_purchases) AS p WHERE `status` > 0 AND user_id` = `musers`.`id`) >= :value".$value_counter;
$values[$value_counter] = $cnd['value'];
break;
// REALLY SLOW SUB-QUERY:
case 'never_purchase':
// Here I am trying to CUT the users by subquery to get only the users who never made a puchase.
$sql .= ' AND (SELECT COUNT(*) FROM (SELECT user_id FROM enswitch_new_iphone_purchases
UNION
SELECT user_id FROM enswitch_new_android_purchases) AS p WHERE `status` = 0 AND `user_id` = `musers`.`id`) = 0';
break;
}
}
$query = DB::query(Database::SELECT, $sql);
$query->bind(':mobile_type', $mobile_type);
// Looping the values and binding it into the SQL query!
foreach ($values as $k => $v) {
$query->bind(':value'.$k, $values[$k]);
}
// Executing query
$result = $query->execute();
return array('total_users' =>$result[0]['total'], 'affected_users'=>$result[0]['users']);
}
EDIT:
The Slowest Query as Requested: (MySQL)
SELECT COUNT(*) AS `users`,
( SELECT COUNT(*)
FROM `enswitch_mobile_users`
) AS `total`
FROM `enswitch_mobile_users` AS `musers`
WHERE `musers`.`phone_type` = 'iphone'
AND ( SELECT COUNT(*)
FROM ( SELECT `status`,
`user_id`
FROM `enswitch_new_iphone_purchases`
UNION
SELECT `status`,
`user_id`
FROM `enswitch_new_android_purchases`
) AS `p`
WHERE `p`.`status` > 0
AND `p`.`user_id` = `musers`.`id`
) >= 2
The subquery in the second SELECT column will execute for every m_users row that passes the WHERE condition:
SELECT
COUNT(*) AS users,
(SELECT COUNT(*) FROM enswitch_mobile_users) AS total <-- here's the problem
FROM enswitch_mobile_users AS musers
WHERE musers.phone_type = whatever
If I'm reading this correctly, you need a one-row result with the following columns:
users - number of enswitch_mobile_users rows with the specified phone_type
total - count of all enswitch_mobile_users rows
You can get the same result with this query:
SELECT
COUNT(CASE WHEN musers.phone_type = whatever THEN 1 END) AS users,
COUNT(*) AS total
FROM enswitch_mobile_users
The CASE checks for the phone type, and if it matches the one you're interested it it yields a 1, which is counted. If it doesn't match, it yields a NULL, which is not counted.
I am attempting to count comments on a particular page with the following problematic sql query:
$query = "SELECT * FROM `comments` WHERE is_approved = '1' AND page_id = '943'"
$query = mysql_query($query);
$total = mysql_num_rows($query);
echo $total;
the problem is it is outputting 0 and not 2.
The tables are as follows:
pages:
id:1 page_id:943
id:2 page_id:978
id:3 page_id:977
comments:
id:2 page_id:1 "hello"
id:3 page_id:1 "great"
id:4 page_id:3 "super"
So really the original query should be getting each comment's true page_id from the page_id as set in the pages tables, as joined by comments.page_id = pages.id
What would the final code look like to either make that join, and/or get that count? Thank you.
Try:
SELECT c.* FROM `comments` c
JOIN `pages` p on c.page_id = p.id
WHERE c.is_approved = '1' AND p.page_id = '943'
"SELECT * FROM comments, pages WHERE comments.page_id = pages.id AND is_approved = '1' AND comments.page_id = '943'"
Try using:
SELECT count(*) as cnt
FROM `comments` c join pages p on c.page_id = p.id
WHERE c.is_approved = '1' AND p.page_id = '943'
It seems like a very poor database design to have two columns with the same name in different tables that mean different things. You should probably change the name of pages.page_id to something else.
And, this returns the count directly, so you can read the value from the row. If you just want the count, there is no reason to return all the matching rows.
no join is needed:
$query = "SELECT * FROM `comments` WHERE is_approved = '1' AND WHERE page_id IN (SELECT id WHERE page_id = '943')"
$query = mysql_query($query);
$total = mysql_num_rows($query);
echo $total;
ofcourse i would suggest a count statement if you do not need/use the data:
$query = "SELECT COUNT(*) as total FROM `comments` WHERE is_approved = '1' AND WHERE page_id IN (SELECT id WHERE page_id = '943')"
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$total = $row['total'];
echo $total;
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
one variable row inside another variable row
I have script something like -
$sql = "SELECT * FROM `users`"
$q = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($q);
$sql1 = "SELECT * FROM `other_table`";
$q1 = mysql_query($sql1) or die(mysql_error());
$row1 = mysql_fetch_array($q1);
$item = $row1[$row['username']];
How can I set one variable row inside another, since it don't work. Basically, I need to select username, and then select column with user username from other table, in which is written user points.
I was thinking about adding -
$sql = "SELECT * FROM `users`"
$q = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($q);
$sql1 = "SELECT `".$row['username']."` FROM `other_table` WHERE `uid` = 1";
$q1 = mysql_query($sql1) or die(mysql_error());
$row1 = mysql_fetch_array($q1);
$item = $row1[xxxxxxxxxx]; // DONT KNOW HOW TO DEFINE IT, so it takes out found variable (there is only one).
I have question already, but not with full info, and I don't know how to delete it :(!
Here is my table -
Users
'id'--'name'
'1'--'Bil'
'2'--'Conor'
'3'--'Ilian'
Other_table (which holds points for users)
'id'--'Bil'--'Conor'--'Ilian'
'1'--'2'--'3'--'55'
Don't ask, why I don't hold the points in the same table, since if I could, I would do that ;)!
It sounds like you need to redesign the tables to start with, I would suggest a table structure like this:
Table Users
ID | Name
Table Points
UserID | Points
This way you can add a foreign key constraint between the tables and then do a simple join query like:
SELECT U.Name, P.Points FROM Users AS U INNER JOIN Points AS P ON U.ID = P.UserID
Then your php code would look like:
$sql = "SELECT U.Name, P.Points FROM Users AS U INNER JOIN Points AS P ON U.ID = P.UserID";
$q = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($q);
Here are the create table queries for you:
CREATE TABLE Users (ID INT NOT NULL AUTO_INCREMENT,
Name VARCHAR(50) NOT NULL, PRIMARY KEY (ID))
CREATE TABLE Points (UserID INT NOT NULL, Points INT,
FOREIGN KEY(UserID) REFERENCES Users(ID) ON UPDATE CASCADE ON DELETE CASCADE)
EDIT:
This should allow you to get the value (NOTE: untested as I don't have a php/mysql instance to mess with currently), but for a more robust solution you really should look into redesigning your table schema.
$userName = $row['username'];
$sql1 = "SELECT [". $userName ."] FROM other_table WHERE [uid] = 1";
$q1 = mysql_query($sql1) or die(mysql_error());
$row1 = mysql_fetch_array($q1);
$item = $row1[$userName];
SELECT users.id, users.name, other_table.points FROM users LEFT JOIN other_table ON other_table.name=users.name
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