SQL Select from table using the outcome of a previous SELECT query? - php

Basically, I want to Select from one table, then using the outcome select from another table and then finally echo the values I selected.
DECLARE #var1 int; /*This should become the result of Table1.Column1 */
DECLARE #var2 nchar(50); /*This should become the result of Table1.Column2 */
DECLARE #var3 nchar(50); /*This should become the final result */
SELECT #var1 = (SELECT Column1 FROM Table1 WHERE Column3 = '12345')
SELECT #var2 = (SELECT Column2 FROM Table1 WHERE Column3 = '12345')
SELECT Column1 FROM Table2 WHERE Id = #var1
Then once this has finished, PHP echo var1, var2 and var3.
I know this would be easier with 2 seperate queries but I want to keep it clean and not have to do that, does anyone know how I can do this? I know the code I provided is completely off but hopefully it makes sense what I'm trying to do.

This is what a join is for. Your first two example SELECT statements can be combined into a single statement like:
SELECT column1, column2 FROM table WHERE column3 = '12345';
You can then JOIN your table2:
SELECT
t1.column1,
t1.column2,
t2.column1
FROM Table1 T1
LEFT OUTER JOIN Table2 T2
ON t1.column2 = t2.id
WHERE t1.Column3 = '12345';
Using a LEFT OUTER JOIN here since that is the type of join that foots best with your psuedo code above. Essentially "SELECT all records that match the WHERE criteria from table1 and any records that might also match from table2 based on that ON condition. If no records match in Table2 for that ON Condition then just return NULL for that table2 column".
The result set returned will have three fields which are functionally equal to your #var1, #var2 and #var3

You can do this in two ways. Since it seems that your first query returns a single result, you can use that subselect as the expression in your second query:
SELECT #var2 = (SELECT Column2 FROM Table1 WHERE Column3 = (SELECT Column1 FROM Table1 WHERE Column3 = '12345'))
or you could use a common table expression (I'm assuming SQL Server):
with CTE_Table (var1) as
(SELECT Column1 FROM Table1 WHERE Column3 = '12345')
SELECT #var2 = (SELECT Column2 FROM Table1 WHERE Column3 = (select var1 from CTE_Table))
Something of that circumference should work. I just entered that here for context, but have not tested for syntax.

Related

How to compare 2 columns of 2 different tables on Mysql

I did something like this with PHP and it works.
$table1 = $DB->query('SELECT column1 FROM table1');
$table2 = $DB->query('SELECT column2 FROM table2'); # excludes
$diff = "'" . implode("','", array_diff($table1, $table2)) . "'";
$DB->query("DELETE FROM table1 WHERE column1 IN ({$diff})");
My question is how to do the same with one sql statement, instead of writing 3 different and doing the array_diff/implode thing.
Unfortunately I have limited sql knowledge but I'm pretty sure it's possible, I think with JOIN but after 2 hours still can't find how. :/
You can use sub-query. The query will be like below.
Delete from Table1
where column1 in (
SELECT column2 FROM table2
)
You can try this:
DELETE t1
FROM Table1 t1
INNER JOIN Table2 t2 ON t1.column1 = t2.column2;
Here is a solution
DELETE FROM table1 WHERE column1 IN (
SELECT t0.column1 FROM
(SELECT column1 FROM table1) AS t0
JOIN
(SELECT column2 FROM table2) AS t1
ON t0.column1 = t1.column2)
Thanks.

How to search into table B if the result of searching into table A is zero?

I have three tables and I need to search in the first one, it there isn't any result, then search into second one and so on ..!
Here is my code:
// connecting to database
$stm1 = $this->dbh->prepare(" select * from table1 where col = :name; ");
$stm1->bindValue(":name", $name, PDO::PARAM_STR);
$stm1->execute();
$which_table = "table1";
// the result of searching into table1 is zero, then search into table2
if (!$stm1->rowCount()) {
$stm2 = $this->dbh->prepare(" select * from table2 where col = :name; ");
$stm2->bindValue(":name", $name, PDO::PARAM_STR);
$stm2->execute();
$which_table = "table2";
// the result of searching into table2 is zero, then search into table3
if (!$stm2->rowCount()) {
$stm3 = $this->dbh->prepare(" select * from table3 where col = :name; ");
$stm3->bindValue(":name", $name, PDO::PARAM_STR);
$stm3->execute();
$which_table = "table3";
// the result of searching into table3 is also zero
if (!$stm3->rowCount()) {
$which_table = 'none of them';
}
}
}
My code works as well, But it is slow, How can I optimize it and make it faster? As you see, there is three separated query and multiple if-statement .. How can I reduce them? Generally How can I improve that code? Can I do that using pure-sql?
If you code is slow, then you probably just need indexes:
create index idx_table1_col on table1(col);
create index idx_table2_col on table2(col);
create index idx_table3_col on table3(col);
With indexes, you can also phrase the query as a single statement, assuming the columns in the tables are the same:
select t1.*
from table1 t1
where t1.col = :name
union all
select t2.*
from table2 t2
where t2.col = :name and
not exists (select 1 from table1 t1 where t1.col = :name)
union all
select t3.*
from table3 t3
where t3.col = :name and
not exists (select 1 from table1 t1 where t1.col = :name) and
not exists (select 1 from table2 t2 where t2.col = :name);
This is a more complex query, but your code would only require a single query. And, with indexes, it should be very fast.
My code works as well, But it is slow, How can I optimize it and make it faster?
Add index for the column col
By the way, you may add limit 1 to your queries. It'll help you you have zillions of values in your tables to match

compare two table with row and column

I have two tables table1 and table2
In table1 fieldname is cert_no and in table2 fieldname is cer1,cert2,cert3,cert4,cert5
The value which was not in table2 (cer1,cert2,cert3,cert4,cert5) alone want to display
If both table has same value only transfile_file want to display
SELECT *
FROM table1
WHERE folio = '123456'
AND cm_flag !='X'
AND certificate_no NOT IN
(SELECT CONCAT(certno1,certno2,certno3,certno4,certno5,certno6,certno7,certno8,certno9,certno10)
FROM table2
WHERE tofolio = '123456'
)
If you use for example Microsoft SQL Server there is a function EXCEPT that return the different rows between 2 tables with the same fileds (same name, same types and same positions). In Oracle there is MINUS operation that is the same of EXCEPT.
In MySQL does not implement a EXCEPT or MINUS operation which is a unfortunate as it can allow for better execution plans in some cases than the alternatives.
This is a valid aternative and more performing than use NOT IN operation: realize a join is the best solution in SQL.
enter code here
SELECT a.*
FROM table1 as a
LEFT JOIN table2 as b
ON a.tofolio = b.tofolio
WHERE b.tofolio IS NULL
Try:
SELECT * FROM table1 WHERE folio = '123456' AND cm_flag !='X' AND certificate_no NOT IN (SELECT CONCAT(certno1,',',certno2,',',certno3,',',certno4,',',certno5,',',certno6,',',certno7,',',certno8,',',certno9,',',certno10) FROM table2 WHERE tofolio = '123456')

How to know the table name inside a fetch_array

I am doing a query with union from two different tables and then on the fetch_array loop I would like to know from which table out of the two I am actually grabbing, anyway without adding a flag into the table's structures. ?
The flag doesn't need to be in the table, but can easily be in the query:
SELECT 'table1' as t, ... FROM table1
UNION
SELECT 'table2' as t, ... FROM table2
...
echo $row['t'];
You don't have to select fields from a table, you can simply "select a string literal" too.
If you have columns with identical name in both tables you could use as
SELECT table1.col1 as col1, table1.col2, table1.col3 FROM table1
UNION
SELECT table2.col1 as col4, table1.col5 FROM table2
then when you do $data = fetch_assoc($q) you will have
$data["col1"] // table1.col1
$data["col2"] // table1.col2
-----------------------------
$data["col4"] //table2.col1

PHP/SQL Statement repeating a query

If I have a list of ID's that I have selected from a statement
SELECT id FROM myTable WHERE name = 'TEST'
This would return just the ids (1001, 1002, 1003, etc...) Then I want to perform another SELECT statement to retrieve all the titles for all those ids.
SELECT title FROM myTable2 WHERE id = XXXX
the id in table2 is the foreign key of table2. id in myTable is the Primary Key. How can I go about retrieving all the titles from those ids. I was thinking about storing all the results of the first select statement in an array, and then using a while loop to iterate through the list and return each result into another array, but my fear is that when the database gets big if it has to return 1000 rows that could be some bad overhead. So in PHP or SQL what is the best way to perform this?
You can use a subquery:
SELECT title
FROM myTable2
WHERE id IN (
SELECT id
FROM myTable
WHERE name = 'TEST'
)
Another way to do it would to be use a JOIN, to avoid the sub-query:
SELECT title
FROM myTable2
LEFT JOIN myTable
ON myTable.id = myTable2.id
WHERE myTable.name = 'TEST'
You should just be able to select them at the same time.
SELECT a.id, b.title
FROM myTable a, myTable2 b
WHERE a.name = 'TEST' AND b.id = a.id;
to select both:
SELECT id, title FROM mytable WHERE name="TEST"
or to select the whole row
SELECT * FROM mytable WHERE name="TEST"
if its two tables you are selecting from:
SELECT id, title FROM mytable A JOIN mytable2 B USING (id)

Categories