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)
Related
I’m building a search function for a real estate app and I’m trying to display 100 filtered properties per page.
My SQL for the first load looks like this:
$sql = "SELECT * FROM table WHERE bedrooms = 2 LIMIT 100";
Subsequent loads are basically the same with an additional offset. The offset is defined by the page number subtracted by one, multiplied by the properties per page.
$page = $_GET[‘page’] - 1;
$propertiesPerPage = 100;
$offset = $page * $propertiesPerPage;
$sql = "SELECT * FROM table WHERE bedrooms = 2 LIMIT 100 OFFSET ".$offset;
This works great. Now I just want to do the same thing, but get properties from two tables instead of just one. I'm trying this:
$sql = "SELECT * FROM table1 WHERE bedrooms = 2";
$sql .= " UNION ALL ";
$sql .= "SELECT * FROM table2 WHERE bedrooms = 2 LIMIT ".$propertiesPerPage." OFFSET ".$offset;
However, because each table has a few different columns than the other, I get this error:
The used SELECT statements have a different number of columns
Both tables have 60 or more columns but most of the columns are the same.
Is there a way to select rows from both tables where WHERE conditions are met?
Also, how does OFFSET work with JOINs? How can I "paginate" the results being selected from two tables?
Your query needs to be similar to this:
$sql = "
SELECT * FROM
(
(SELECT col1, col2, col3, col4 FROM table1 WHERE bedrooms = 2)
UNION ALL
(SELECT col1, col2, col3, NULL AS col4 FROM table2 WHERE bedrooms = 2)
) AS myalias
LIMIT ".$propertiesPerPage." OFFSET ".$offset;
A couple things:
Selected columns listed in corresponding positions of each SELECT statement should have the same data type. (http://dev.mysql.com/doc/refman/5.7/en/union.html)
Let's say you want it to return all the rows but there are data type mismatches or one table has entirely different columns. You can still retrieve the data from table1 that has the data but if table2 does not have that column then you would need something like NULL AS col4.
The reason we use the union as a nested query is because the limit will be applied after both the queries have been joined together.
Generally when doing unions you'll be very specific on which columns you'll be fetching. If you want just 30 columns, you'll need to specify all of those columns in your select queries used for the union. If it seemed necessary, you could use a PHP variable to define it to reduce the repetition.
I want to make 2 mysqli queries. But if there are values in the second query that are Identical to the values yielded from the first query I want to exclude those values from the result set. What I have now only seems to work for 1 identical value. the rest of the identical values are shown. how should I change this? Thanks.
$query1 = $db->query("SELECT colTab1 FROM table1");
while ($result1 = $query1 ->fetch_assoc()) {
$query2 = $db->query("SELECT colTab2 FROM table2 WHERE colTab2 <> $result1[colTab1]");
echo $result1['colTab1']."<br>";
}
while ($result2 = $query2 ->fetch_assoc()) {
echo $result2['colTab2']."<br>";
}
}
Well, you can modify your second query as follows:
SELECT colTab2 FROM table2 WHERE colTab2 NOT IN (SELECT colTab1 FROM table1)
Or maybe you just want to select the UNION of the two tables (which will omit duplicates by default):
SELECT colTab1 FROM table1
UNION
SELECT colTab2 FROM table2
(Note that relying on UNION to omit duplicates between the two recordsets is not quite the same thing, as any duplicates that exist within each recordset will also be omitted; if that is a concern, one can SELECT DISTINCT ... UNION ALL SELECT DISTINCT ... instead).
Just run one query; why bring back data from the database to filter on? Filter in the DB.
SELECT colTab2
FROM table2
WHERE colTab2 NOT IN (
SELECT colTab1
FROM table1
)
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 table called replies and it has a column named topic_id.
What I want to do is count how many rows have the topic_id 1.
I tried
SELECT COUNT(*)
FROM [***].[replies]
WHERE [***].[topic_id] = '1'
But in this case I don't know if this is a valid query. If it is, how can I pull it back into a variable called $num_rows in my php code?
Note: * is actually a prefix I covered.
Something like this should work:
--declare the variable
DECLARE #num_rows INT
--get the total number of rows
SELECT #num_rows = COUNT(*) FROM replies WHERE topic_id = 1
--get a distinct count of rows (if for some reason you need it)
SELECT #num_rows = COUNT(DISTINCT reply_id) FROM replies WHERE topic_id = 1
--return the result set
SELECT #num_rows AS num_rows
If you just want to return a column called num_rows though, this would be a much more efficient approach:
SELECT COUNT(*) AS num_rows FROM replies WHERE topic_id = 1
I have an array of products IDs and I need to find the IDs that are not present in the database. Sure I can do it like this:
// IDs in database: 1, 2, 3, 4, 5.
$products = array(4, 5, 6, 7);
$in_db = $db->exec("SELECT `id` FROM `table` WHERE `id` IN (" . implode($products) . ");");
$in_db_ids = array();
foreach($in_db as $i){
$in_db_ids[] = $i['id'];
}
$missing = array_diff($products, $in_db_ids);
But this is long and boring. I thought also about something like this:
// this query would be generated with PHP using an implode or something
$query = "
SELECT `t`.`id` as `missing`
SELECT 4 as `id` UNION SELECT 5 UNION SELECT 6 UNION SELECT 7
LEFT JOIN `table` USING(`id`)
WHERE `missing` is NULL;
";
$missing = $db->exec($query);
But this is so inelegant.
I think there should be a proper way to write that SELECT x UNION SELECT y UNION SELECT z, or there may be another nice way to do this check.
What do you think, guys?
To do it in the MySQL database, you will need a table or a temporary table that has a number of rows equal to the highest index in the table you are scanning for missing blanks. There is no way around this -- MySQL always "loops" through tables, it isn't a procedural language where you can set up your own loop.
That being said, if you create or have a table of sufficient size, you can create the natural number sequence using a user variable. Let's call the big table bigtable (it doesn't matter what columns are in it - we just need a name of one of the columns - I use 'acolumn').
set #row = 0;
select n from
(select #row := #row + 1 as n from bigtable) as t
left join mytable on mytable.id = t.n
where mytable.acolumn is null;
Let me know if this needs a little more explanation.