Multi select on same database with different conditions - php

i have pagination and i should call database for two times!
it's meant i should call :
SELECT COUNT(users_id) FROM users
for get all of database rowCount
and in another database fetch i have :
SELECT * FROM users ORDER BY users_id ASC LIMIT 1, 2
for create pagination
is there anyway to create one database call and get the same results ?
i try this:
SELECT COUNT(users_id),* FROM users ORDER BY users_id ASC LIMIT 1, 2
but this, call just 2 (count users_id) and broke pagination :(
Thanks and sorry for my poor english.

You can get this with 2 Queries:
1) first get your result with LIMIT and OPTION SQL_CALC_FOUND_ROWS
2) get the num rows without LIMIT
SELECT SQL_CALC_FOUND_ROWS t.* FROM yourTable 1 LIMIT 2;
SELECT FOUND_ROWS();
sample
mysql> SELECT SQL_CALC_FOUND_ROWS t.* FROM yourTable t LIMIT 2;
+-----+------------+
| id | toDate |
+-----+------------+
| 111 | 2017-03-02 |
| 111 | 2017-03-20 |
+-----+------------+
2 rows in set (0,00 sec)
mysql> SELECT FOUND_ROWS();
+--------------+
| FOUND_ROWS() |
+--------------+
| 4 |
+--------------+
1 row in set (0,00 sec)
mysql>

No, it's not possible because it returns different result sets - first query returns single-column result with an int, the other query returns all columns from users.
You need to do two separate queries for this.

Related

get the latest, second to the latest, and 3rd to the latest record from database

is there any way to get the latest, second to the latest, and 3rd to the latest record from database in different query? because i want to use each query for my slider image/content. please tell me if my question is confusing.
i know there's a way using order by desc id or date, limit 3 , but that comes in just one query, i was wondering if there's a way to just fetch the second to the latest and 3rd to the latest record. i know that the latest query can be written like order by desc id or date, limit 1 , i just do not know how it is to query with the 2nd and 3rd to the latest record.
Here is one solution using LIMIT and OFFSET.
-- latest
order by desc id/col_date desc limit 1
-- 2nd to latect
order by desc id/col_date desc limit 1,1
-- 3rd to latect
order by desc id/col_date desc limit 2,1
Demo:
mysql> select * from (select 1 as a union select 2 union select 3) t;
+---+
| a |
+---+
| 1 |
| 2 |
| 3 |
+---+
3 rows in set (0.00 sec)
mysql> select * from (select 1 as a union select 2 union select 3) t order by a desc limit 1;
+---+
| a |
+---+
| 3 |
+---+
1 row in set (0.00 sec)
mysql> select * from (select 1 as a union select 2 union select 3) t order by a desc limit 1,1;
+---+
| a |
+---+
| 2 |
+---+
1 row in set (0.00 sec)
mysql> select * from (select 1 as a union select 2 union select 3) t order by a desc limit 2,1;
+---+
| a |
+---+
| 1 |
+---+
1 row in set (0.00 sec)
Reference:
http://dev.mysql.com/doc/refman/5.7/en/select.html
The LIMIT clause can be used to constrain the number of rows returned
by the SELECT statement. LIMIT takes one or two numeric arguments,
which must both be nonnegative integer constants, with these
exceptions:
Within prepared statements, LIMIT parameters can be specified using ?
placeholder markers.
Within stored programs, LIMIT parameters can be specified using
integer-valued routine parameters or local variables.
With two arguments, the first argument specifies the offset of the
first row to return, and the second specifies the maximum number of
rows to return. The offset of the initial row is 0 (not 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15

MySQL Round Robin Select

I have a table of urls. I need to select 1, in round robin. Hoping to display 1 per pageview OR per Visitor and show each 20 times if I have 100 pageviews OR Visitors.
Essentially: SELECT url FROM table LIMIT 1 (in rotation)
+-------+---------------------+
| id | url |
+-------+---------------------+
| 1 | http://google.com |
| 2 | http://yahoo.com |
| 3 | http://ebay.com |
| 4 | http://anything.com |
| 5 | http://other.com |
+-------+---------------------+
If I understand correctly what you mean by round-robin then you can do something along the lines of
SELECT id, url
FROM urls u CROSS JOIN
(
SELECT MIN(id) min_id, MAX(id) max_id
FROM urls
) m
WHERE id > IF(? >= max_id, 0, ?) -- last shown id goes here instead of placeholders
ORDER BY id
LIMIT 1;
Store (in session, file, another table, etc.) and pass to your query the last shown id or 0 for the initial query.
This will give you the next row or first again if you reached the last one.
This query will still work if you have gaps in ids.
Here is a SQLFiddle demo
You can do using order by rand()
SELECT * FROM table ORDER BY rand() LIMIT 1
You can use RAND() function in your ORDER BY clause:
SELECT * FROM tableName ORDER BY RAND() LIMIT 1
Is this what you want to achieve?

Count/Group By/Order By is only showing the count of the most common value and not the string itself

I'm querying a table to find the most common string in a column. However, it doens't seem to be working correctly. It should be returning the value of the most common string, but is instead returning the number of times the most common string exists. The query is:
SELECT COUNT(field_review_bar_tab_2_value) AS `Rows`
FROM (field_data_field_review_bar_tab_2)
GROUP BY (field_review_bar_tab_2_value)
ORDER BY `Rows` DESC
LIMIT 1
Table structure, simplified, would be something to the effect of:
-----------------------------------
| ID | field_review_bar_tab_2_value |
|----+----------------------------- |
| 1 | Food Drinks |
| 2 | Drinks |
| 3 | Food Drinks |
| 4 | Food |
-----------------------------------
The query is recognizing that, in the example above, "Food Drinks" is the most common string in the column. But, the query is returning "2" instead of "Food Drinks". Any ideas as to why it would be making the correct query but returning the count of the result instead of the value of the string?
You need to include field_review_bar_tab_2_value in the SELECT list as well. I've switched the aggregate to COUNT(*) here, and included the grouped column in the SELECT.
SELECT
field_review_bar_tab_2_value AS the_most_common_string,
COUNT(*) AS `Rows`
FROM (field_data_field_review_bar_tab_2)
GROUP BY (field_review_bar_tab_2_value)
ORDER BY `Rows` DESC
LIMIT 1
You're selecting the count, not the value. I think you mean:
SELECT field_review_bar_tab_2_value
FROM field_data_field_review_bar_tab_2
GROUP BY field_review_bar_tab_2_value
ORDER BY COUNT(*) DESC
LIMIT 1
Since you're already grouping by the value in question, you can just do COUNT(*)...
You will need to modify your query to return the field itself. Currently the query is only returning the COUNT because that's what is indicated in your select statement. Modify it as follows:
SELECT field_review_bar_tab_2_value AS `MostCommonString`, COUNT(field_review_bar_tab_2_value) AS `Rows`
FROM (field_data_field_review_bar_tab_2)
GROUP BY (field_review_bar_tab_2_value)
ORDER BY `Rows` DESC
LIMIT 1

MySQL use generated column in select query

I have a MySQL query that runs a brief operation (totalling the counts in a select statement) and I want to use the result to do a math operation, but I'm getting an error.
Table:
id | group | count |
-----------------------------
1 1 3
2 1 2
Query:
select id, count,
(select sum(count) from table group by group) as total,
count/total as percent
from table
The error is because there is no real "total" column in the table. How can I make the query work?
You can save total as a variable, then use that in the division calculation.
SELECT
`id`, `count`,
#total:=(SELECT sum(`count`) FROM `table` GROUP BY `group`) AS `total`,
`count`/#total AS `percent`
FROM `table`
NOTE: GROUP is a reserved word in MySQL. You should enclose it (and all other field/table names) in backticks (`).
You can also do this without introducing a variable:
select id,
count,
(select sum(count) from `table` group by `group`) as total,
(select count/total) as percent
from `table`;
Produces:
+------+-------+-------+---------+
| id | count | total | percent |
+------+-------+-------+---------+
| 1 | 3 | 5 | 0.6000 |
| 2 | 2 | 5 | 0.4000 |
+------+-------+-------+---------+
2 rows in set (0.05 sec)
Your problem is that the inner query needs to generate 1 result per row, not 1 for every group. You want to add a where clause in the inner query saying something like
where inner_table.group = outer_table.group
so that only one result is returned.
group is a reserved word in mysql, as is table, you should use it like:
select id, count, (select sum(count) from `table` group by `group`) as total, count/total as percent from `table`
For more information: MySQL Reserved Words
You'll see there that you can actually use count but I would put all table and column names in quotes anyway.
This question already has an answer for MySql but by mistake if anyone lands here for MSSql as i did, it is as simple as below for MSSql
select id, count,
total = (select sum(count) from table group by group),
count/total as percent
from table

How to count and limit record in a single query in MYSQL?

I am searching for records in a table as follows:
SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
Now, I am adding LIMIT to maintain my paging. But when user searches for word 'prashant' then total records I have is 124 for 'prashant'. But as the limit applied to the query so it only fetches 10 records in my PHP script and when I am count the mysql variable in PHP code it returns total records found is 10.
So basically I want to count and Limit using a single query, by making some modification in the above query, I want the total count (124) of records. I don't want to run a separate count(*) query for just counting the total result found by the query.
Thanks.
SELECT SQL_CALC_FOUND_ROWS
Id, Name
FROM my_table
WHERE
Name LIKE '%prashant%'
LIMIT 0, 10;
# Find total rows
SELECT FOUND_ROWS();
more info
MySQL supports doing this using SQL_CALC_FOUND_ROWS as mentioned by Ionut. However, it turns out that in many cases it's actually faster to do it the old fashioned way using two statements, where one of them is a regular count(). This does however require that the counting can be done using an index scan, which won't be the case for this very query, but I thought I'd mention it anyway.
This is for others with the same need (considering it's been 3 years from the time of this question).
I had a similar issue and I didn't want to create 2 queries. So what I did was to create an additional column for the total number and moved the LIMIT and OFFSET clauses at the end:
SELECT SQL_CALC_FOUND_ROWS * FROM (
SELECT `id`, `name`
FROM `my_table`
WHERE `name` LIKE '%prashant%'
) res,
(SELECT /*CEIL(FOUND_ROWS()/10) AS 'pages',*/ FOUND_ROWS() AS 'total') tot
LIMIT 0, 10
So the result is something like
| id | name | total |
+-----+----------------+-------+
| 1 | Jason Prashant | 124 |
| 2 | Bob Prashant | 124 |
| 3 | Sam Prashant | 124 |
| 4 | etc. prashant | 124 |
and I think this solution has no disadvantage in timing because it fetches the result only once, and then uses the already calculated row count for the additional column.
In case of huge tables and selecting multiple fields (not just Id, Name as in your example) i would recommend to use 2 queries. Selecting count(0) first with all those WHERE clauses and only then build the pagination, selecting data etc.
It will work really faster on some popular eCommerce website, for example.
Don't use SQL_CALC_FOUND_ROWS and FOUND_ROWS()
there are the bugs reported
here: https://bugs.mysql.com/bug.php?id=18454
and here: https://bugs.mysql.com/bug.php?id=19553
while on small tables BENCHMARK is dependent more on other things and the resulting time your SELECT will take will be roughly the same as COUNT(0) - SQL_CALC_FOUND_ROWS still puts restraints on LIMIT and ORDER BY database optimizations so if you depend on them don't use SQL_CALC_FOUND_ROWS
on large tables the BENCHMARK difference becomes huge where a COUNT(0) might take 0.003 sec the same SQL_CALC_FOUND_ROWS might now take 20 sec
By all metrices COUNT(0) is the superior choice
COUNT(0) SYNTAX:
(SELECT COUNT(0) FROM tableNames WHERE condition) AS alias
// alias is optional but needed if you need to use the result later
So your total query would look like this
(SELECT COUNT(0) FROM my_table WHERE name LIKE '%prashant%') AS countResults;
SELECT Id, Name FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
And then just call countResults whereever you need it elsewhere...
Another advantage of using COUNT(0) is you can use it for searching both the same table as here or you can use it to search a different table...
So for instance if each person found also has 3, 2, 1, 5 diffenrent jobs respectively... you could just add a
(SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs
inside your original SELECT like this
SELECT Id, Name (SELECT COUNT(0) FROM my_jobs_table WHERE name = name_row_in_jobs_table) AS jobs FROM my_table WHERE Name LIKE '%prashant%' LIMIT 0, 10;
Giving you:
--------------------
| id | Name | jobs |
--------------------
| 1 | Alice| 3 |
--------------------
| 2 | John | 2 |
--------------------
| 3 | Bob | 1 |
--------------------
| 4 | Jill | 5 |
--------------------
So when showing name[3] (ie. Bob) you could also show that Bob has 1 job by calling jobs[3]...

Categories