SELECT user_id,username,full_name,display_name,profile_pic,email,
fb_id,image1,image2,image3,image4,image5,default_pic,
street_address,locality,country,state,is_verified,is_online,
city,image6,image7,image8,image9,image10,last_login,
IFNULL( (
SELECT STATUS
FROM vidioo_contacts
WHERE (contact_id = '55000'
AND user_id = vu.user_id
)
OR (contact_id = vu.user_id
AND user_id = '55000')),0) AS STATUS,
(3959 * ACOS( COS(RADIANS(0)) * COS(RADIANS(latitude)) *
COS(RADIANS(longitude) - RADIANS(0)) + SIN(RADIANS(0)) *
SIN(RADIANS(latitude)))
) AS distance
FROM vidioo_users vu
WHERE user_id != '55000'
AND gender LIKE
( SELECT CASE WHEN show_me = 'everyone'
THEN '%'
ELSE IF(LENGTH(show_me) < 1, '%', show_me)
END
FROM vidioo_users
WHERE user_id = '55000'
LIMIT 1
)
AND IFNULL(vu.is_deleted,0) != 55000
AND vu.user_id NOT IN (
SELECT DISTINCT contact_id
FROM vidioo_blocked_users
WHERE bloked_by_user = 55000
)
AND DATEDIFF(NOW(),last_login) < 7
ORDER BY last_login DESC
LIMIT 0,20
I wish to apply indexing to this query.
If the table has a multiple-column index then mysql uses leftmost prefix of the index. For example you have following select queries -
`SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;`
If an index exists on (col1, col2, col3), only the first two queries use the index. The third and fourth queries do involve indexed columns, but (col2) and (col2, col3) are not leftmost prefixes of (col1, col2, col3).
In your case you must have to create 3 indexes as
Index_1(user_id, gender, last_login)
Index_2(user_id)
Index_3(bloked_by_user)
NOTE:- Too many indexing slow down INSERT query processing.
For more details Click here
In addition to the other suggestions, change AND DATEDIFF(NOW(),last_login) < 7 to
last_login > NOW() - INTERVAL 7 DAY
What you have hides the column last_login inside a function (DATEDIFF), making it unusable with indexing. Then, also, add
INDEX(last_login)
(It may not help, but it may.)
Also, change
AND vu.user_id NOT IN (
SELECT DISTINCT contact_id
FROM vidioo_blocked_users
WHERE bloked_by_user = 55000
)
to
AND NOT EXISTS( SELECT * FROM vidioo_blocked_users
WHERE bloked_by_user = 55000
AND contact_id = vu.user_id )
Together with
INDEX(bloked_by_user, contact_id) -- in either order
Try adding indexes on these four table columns, It should help:
contact_id,
user_id,
is_deleted,
last_login.
Related
I have two tables inside a mysql database. table_1 and table_2
Both of these tables have 4 columns for users
user_1, user_2, user_3 and user_4
Now using PHP I first want to fetch the non-null values from two tables and I use this query.
<?php
$query1 = "
select * from table_1 where user_1!='' and user_1 is not null
union all
select * from table_1 where user_2!='' and user_2 is not null
union all
select * from table_1 where user_3!='' and user_3 is not null
union all
select * from table_1 where user_4!='' and user_4 is not null
";
Then I fetch it and count the entries total = mysqli_num_rows and it gives me correct details as 3.
Similarly I do it for table_2
<?php
$query2 = "
select * from table_2 where user_1!='' and user_1 is not null
union all
select * from table_2 where user_2!='' and user_2 is not null
union all
select * from table_2 where user_3!='' and user_3 is not null
union all
select * from table_2 where user_4!='' and user_4 is not null
";
and it shows me total count as 2 which is correct.
But when I add count1 and count2
$count1 = mysqli_num_rows($data1);
$count2 = mysqli_num_rows($data2);
$total = $count1+$count2;
It shows either 1 or some weird value.Please suggest a fix
Everything depends on what $data1 and $data2 is. If they contain the results of $query and $query2, respectively, then one could expect the result to be 5. However, since your result is different, it follows that $data1 and $data2 is not what you think. So, in order to find out what the problem is, you will need to find out what $data1 and $data2 is. You will need to var_dump them and analyze what their value is, detect the nature of the anomaly. Once that's done, you will need to look at the code and figure out how that value was ending up into your variables.
to getting which column is not empty, you should add some condition as AND and if your fields have whitespace please consider TRIM condition such as:
SELECT * FROM `table_1` WHERE `user_1` IS NOT NULL AND TRIM(column) <> '' union all
notice: if you want use more than one command in php variable as string, you should add semicolon on end of each command
$query ="
SELECT * FROM `table_1` WHERE `user_1` IS NOT NULL AND TRIM(user_1) <> '' union all;
SELECT * FROM `table_2` WHERE `user_2` IS NOT NULL AND TRIM(user_2) <> '' union all;
SELECT * FROM `table_3` WHERE `user_3` IS NOT NULL AND TRIM(user_3) <> '' union all;
"
I have the PHP code:
$query = mysqli_query($mysqli, "SELECT * FROM `table_1`");
$result = mysqli_num_rows($query);
$queryTwo = mysqli_query($mysqli, "SELECT * FROM `table_2`");
$resultTwo = mysqli_num_rows($queryTwo);
$number = $result + $resultTwo;
return $number;
The point is that sometimes, the $number variable is returning NULL,
when it should not supposed to do that.
I have always rows in those 2 tables, and the returned result should not be NULL, ever.
Is this a correct approach to sum the number of rows from 2 tables? I don`t understand why sometimes I get NULL instead of a number.
Well, I would suggest you to do it like
select ( select count(*) from Table1 ) + ( select count(*) from Table2 )
as total_rows
executing this query and getting the value of total_rows will return you true result
Or you can create a stored procedure to do the same thing. as explained below
CREATE PROCEDURE sp_Test
AS
-- Create two integer values
DECLARE #tableOneCount int, #tableTwoCount int
-- Get the number of rows from the first table
SELECT #tableOneCount = (SELECT COUNT(*) FROM Table1
WHERE WhereClause)
SELECT #tableTwoCount = (SELECT COUNT(*) FROM Table2
WHERE WhereClause)
-- Return the sum of the two table sizes
SELECT TotalCount = #tableOneCount + #tableTwoCount
Why don't you go with only one query like this:
you will have the result directly in one step and it will avoid contacting the DB twice to fetch intermediate result and it will also simplify your program!
SELECT
(select count(*) from table_1)
+
(select count(*) from table_2)
So here's my mission: return a random row from a MySQL table with no primary key. A quick search returned this page and this solution:
SELECT column FROM table
ORDER BY RAND()
LIMIT 1;
Unfortunately, the solution is not optimized, as this site makes clear. They propose the following fix, which is in PHP:
$offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` ");
$offset_row = mysql_fetch_object( $offset_result );
$offset = $offset_row->offset;
$result = mysql_query( " SELECT * FROM `table` LIMIT $offset, 1 " );
Good enough as I'll be publishing this on a page, but in the meantime I need to try it in raw MySQL. So I punched in:
SELECT *
FROM `table`
LIMIT (SELECT FLOOR(RAND() * COUNT(*)) FROM `table`), 1;
... and got the following error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(SELECT FLOOR(RAND() * COUNT(*)) FROM `table`), 1' at line 3
But I don't understand, because the individual components work perfectly. If I enter:
SELECT FLOOR(RAND() * COUNT(*))
FROM `table`
... I get a random number from 0 up to the number of rows minus 1. Likewise, if I enter:
SELECT *
FROM `table`
LIMIT 2, 1
... I get the third row in the table (or the fourth row if I substitute 3 for 2, etc.)
What am I doing wrong?? Thanks in advance!
If you want a random sample, the following may be fast enough:
SELECT *
FROM `table` t cross join
(select count(*) as cnt from table t) const
WHERE rand() <= 100 / cnt
ORDER BY rand()
LIMIT 1 ;
This does have to scan the table, but the sort is on roughly 100 rows, which should be fast enough.
I know that this must be a very basic question, but I've not found an answer.
As the title says, I would like the query the record that holds the max value of a specific column.
I use the following code to achieve that:
SELECT * FROM `table_name` ORDER BY `column_with_specific_max_value` DESC LIMIT 1
I would like to know if there is an other way to achieve the same result (more parsimonious)? I know that SQL has a function MAX(column) but it's not working the way I want. I tried this:
SELECT * FROM `table_name` WHERE `column_with_specific_max_value`=MAX(`column_with_specific_max_value`)
and this:
SELECT *, MAX(`column_with_specific_max_value`) FROM `table_name`
What happen if the column_with_specific_max_value has 2 rows with the same max value? will it return both rows?
What about?
select * from table1
where score in (select max(score) from table1)
Or even without a max:
select * from table1
where score >= all (select score from table1)
Any of those WILL return all rows with the max value. You can play with it here.
If your table has an auto-increment column to work with, you could do something like...
select
YT3.*
from
( select
MAX( YT2.AutoIncColumn ) as ReturnThisRecordID
from
( select max( YT1.WhatColumn ) as MaxColumnYouWant
from YourTable YT1 ) JustMax
Join YourTable YT2
on JustMax.MaxColumnYouWant = YT2.WhatColumn ) FinalRecord
JOIN YourTable YT3
on FinalRecord.ReturnThisRecordID = YT3.AutoIncColumn
I would also ensure this is a column that SHOULD have an index on it, otherwise, you'll always be doing a table scan.
I have a sql query for getting first 40 list of users.I want to retrieve one user always in that list.Is their any method in query specifying the user id with the limit
The best way I can think of is:
SELECT * FROM tbl WHERE userid='your-user-id' UNION SELECT * FROM tbl WHERE userid!='your-user-id' LIMIT 39
Basically, you select your user, and then you select 39 others. You use UNION to conjoin the two SELECT results.
SELECT
*
FROM
`users`
WHERE
`user_id` != 12345
LIMIT 39
UNION SELECT
*
FROM
`users`
WHERE
`user_id` = 12345
ORDER BY `user_id`
;
This will give you first 39 users + user with user_id=12345.
Select * from table order by userd_id limit 40
I guess that would be
(SELECT * from users limit 39)
UNION ALL
(SELECT * from users where userid='your-user-id')
As most of the options are already provided, check if this can help you
select name from user_details where id = user_id || id != user_id order by field (id,user_id) desc limit 40;
This will give you combine results & if you want your specified user id will always come on top.