I have a table (country_table) with a list of all countries and their respective ids.
|country_id|country_name|
|ES |Spain |
.
.
.
I have an array, fetched from another table using fetch_array that looks like this:
$array = Array(
[0]=>Array([country_id]=>'ES')
[1]=>Array([country_id]=>'DE')
[2]=>Array([country_id]=>'GB'))
How can I select the records (country_id and country_name) from country_table that do not exist in the table but exist in the array?
$sql ="SELECT country_id, country_name FROM country_table
WHERE country_id NOT IN (". implode(",", $array) .")";
implode() function will generate comma-seprated string representation of array elements .
This is the sql.
select country_id, country_name from table where country_id not in ('ES','DE','GB');
// gather unwanted id's first
$notInIds = array();
foreach ($array as $arr) $notInIds[] = $arr['country_id'];
// prepare query
$query = 'SELECT `country_id`, `country_name` FROM `your_table`
WHERE `country_id` NOT IN (' . implode(',',$notInIds) . ')';
// then execute it
For the question: "How can I select the records (country_id and country_name) from country_table that do not exist in the table but exist in the array?"
I guess you have to write some code (eg. in PHP) in order to achieve the result you want.
The problem is that you can not display data that is not in the table (eg. country_name), that's not possible as you don't know this data. The only possibility would to show the country_id's which are in the array and not in the table as this is the only data you have...
Related
I need help to create an SQL query in order to SUM the values of specific column from all tables LIKE table_% as the tables will grow over time and this must cater for new table names based on the format below
Scheme Name: database_01
Table Names: tb_data_'YEAR'_'MONTH'
YEAR and MONTH are both values which range from all 12 months and years from 2011 to 2018.
Each Table contains a column called TOTAL_VALUE. I have a php script that triggers an SQL query to pull data from the database.
I would like to SUM the total of each tables TOTAL_VALUE column and save the value for my script below to push the array.
$sql = "SELECT TOTAL_VALUES FROM tb_data_2017_october";
$result = mysqli_query($conn, $sql);
$data = array(); while($enr = mysqli_fetch_assoc($result)){
$a = array($enr['TOTAL_VALUES']);
foreach ($a as $as){
echo "'".$as."', ";}
array_push($data, $as); }
I have been trying to alter the SQL with options such as:
SELECT id FROM table1
UNION
SELECT id FROM table2
UNION
SELECT id FROM table3
UNION
SELECT id FROM table4
However i need to cater for the ability to check all tables that are like tb_data_%
See this question for information about getting the list of tables: Get table names using SELECT statement in MySQL
You can get the list of tables in one query result, and then query each table. I'll rework your code slightly to give an example:
// Get the tables
$tables_sql = "SELECT table_name
FROM information_schema.tables
WHERE table_schema='<your DB>'
AND table_name LIKE 'tb_data%'";
$tables = mysqli_query($conn, $sql);
// Iterate over the tables
while($table = mysqli_fetch_assoc($tables)){
{
/*
* Your code
*/
// This query assumes that you can trust your table names not to to an SQL injection
$sql = "SELECT TOTAL_VALUES FROM " . $table['table_name'];
$result = mysqli_query($conn, $sql);
$data = array(); while($enr = mysqli_fetch_assoc($result)){
$a = array($enr['TOTAL_VALUES']);
foreach ($a as $as){
echo "'".$as."', ";
array_push($data, $as); }
}
You can do whatever you need once your have your list of tables. You can build one big union query (which would be more efficient than querying each table individually), or feed the tables to the MERGE engine, as in barmar's answer
Use the MERGE storage engine to create a virtual table that combines all the monthly tables.
CREATE TABLE tb_all_data (
...
) ENGINE=MERGE UNION=(tb_data_2017_october, tb_data_2017_november, ...);
List all the tables in the UNION= list, and update it whenever you create a new table.
Then you can just query from tb_all_data.
Try this- it will loop through all the tables with the pattern you want and create sums for you:
declare #table table (rowid int identity, name varchar(max))
insert #table
select name from sys.tables where name like '%yourname%'
declare #holding table (name varchar(max), sumvalue int)
declare #iterator int = 1
declare #tablename varchar(max)
while #iterator<=(select max(rowid) from #table)
begin
select #tablename=name from #table where rowid=#iterator
insert #holding
exec('select '+#tablename+' sum(TOTAL_VALUE)TOTAL_VALUE from '+#tablename+' group by +'+#tablename+'')
set #iterator=#iterator+1
end
select * from #holding
I have a session that contains an array and that array is filled with id's. What is the best way to select all the rows from a MySQL table that correspond to these id's?
So I need something like:
SELECT * FROM table WHERE id = $_SESSION['ids']
Obviously, this doesn't work, since $_SESSION['ids'] is an array.
SELECT *
FROM
table
WHERE
find_in_set(id, $_SESSION['ids'])>0
You can just use IN SQL operator.
In this case your query will look like
$sql = 'SELECT * FROM table WHERE id IN ("' . implode('","', $_SESSION['ids'] . '")';
This code will produse a query like following:
SELECT * FROM table WHERE id IN ("1", "2", "foo");
Hope it helps
HI Try This,
$var = $_SESSION['ids'];
and then fire your query as
$sql = SELECT * FROM table WHERE id = '$var';
As i am far from an expert in php this got me stunned and i can't seem to make a script for it.
Lets see if i can explain this as clearly as possible.
Lets say i have table1 and table2
Table1 = (teamid, name, round1pos, round1score, round2pos, round2score)
Table2 = (id, tournamentid, teamid, name, round1pos, round1score, round2pos, round2score...till round10pos/round10score)
When copied from table1 to table 2 i want to add 2 fields in front of it. (id and tournamentid)
The problem i am facing is that Table1 has a different amount of roundxpos/roundxscore each time.
Basically what i want to do is once a tournament is over i want to delete the table. but copy the data inside it to another table to archive the results. but each tournament can have a different size of rounds.
I hope someone can understand what i am trying to achieve +_+.
You should create a third table, remove the roundX columns from your existing tables and reference them with their IDs.
rounds: team_id, tournament_id, no, pos, score
You should normalize your tables but in the meantime....
I'm assuming the main problem is handling the variable number of roundxpos and roundxscore columns in the code.
Hope this helps:
Get the results of this query: SHOW COLUMNS FROM Table1 WHERE Field LIKE 'round%pos'
Get the results of this query: SHOW COLUMNS FROM Table1 WHERE Field LIKE 'round%score'
Create the table2 inserts by looping through field names
//example, assuming results are fetched into an associative array
$query = "INSERT INTO table2 (tournamentid, teamid, name)";
foreach($roundpos_fields as $f){ $query .= "," . $f['Field']; }
foreach($roundscore_fields as $f){ $query .= "," . $f['Field']; }
$query .= "( SELECT $tournamentid, '' teamid, name";
foreach($roundpos_fields as $f){ $query .= "," . $f['Field']; }
foreach($roundscore_fields as $f){ $query .= "," . $f['Field']; }
$query .= ")";
Ok, normally I know you would do something like this if you knew the array values (1,2,3 in this case):
SELECT * WHERE id IN (1,2,3)
But I don't know the array value, I just know the value I want to find is 'stored' in the array:
SELECT * WHERE 3 IN (ids) // Where 'ids' is an array of values 1,2,3
Which doesn't work. Is there another way to do this?
Use the FIND_IN_SET function:
SELECT t.*
FROM YOUR_TABLE t
WHERE FIND_IN_SET(3, t.ids) > 0
By the time the query gets to SQL you have to have already expanded the list. The easy way of doing this, if you're using IDs from some internal, trusted data source, where you can be 100% certain they're integers (e.g., if you selected them from your database earlier) is this:
$sql = 'SELECT * WHERE id IN (' . implode(',', $ids) . ')';
If your data are coming from the user, though, you'll need to ensure you're getting only integer values, perhaps most easily like so:
$sql = 'SELECT * WHERE id IN (' . implode(',', array_map('intval', $ids)) . ')';
If the array element is not integer you can use something like below :
$skus = array('LDRES10','LDRES12','LDRES11'); //sample data
if(!empty($skus)){
$sql = "SELECT * FROM `products` WHERE `prodCode` IN ('" . implode("','", $skus) . "') "
}
If you use the FIND_IN_SET function:
FIND_IN_SET(a, columnname) yields all the records that have "a" in them, alone or with others
AND
FIND_IN_SET(columnname, a) yields only the records that have "a" in them alone, NOT the ones with the others
So if record1 is (a,b,c) and record2 is (a)
FIND_IN_SET(columnname, a) yields only record2 whereas FIND_IN_SET(a, columnname) yields both records.
is there a mysql statemnet that goes through every table in a data base and says if applicationid =123 or schoolid=123 or familyid = 123 DELETE THE WHOLE record? i need to write a php script that will do this.
SELECT TABLE_NAME, GROUP_CONCAT(DISTINCT COLUMN_NAME SEPARATOR ',') AS columns
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'yourdatabasename'
AND COLUMN_NAME IN ('applicationid', 'schoolid', 'familyid')
GROUP BY TABLE_NAME
The result will be an array of each table, and the columns that it has (only from the set of `applicationid, schoolid, familyid) as a comma separated field.
foreach ($results as $result) {
$cols = explode(',', $result['columns']);
foreach ($cols as &$col) {
$col .= ' = 123';
}
$sql = 'DELETE FROM '. $result['TABLE_NAME'].
' WHERE ' . implode(' OR ', $cols);
}
That'll generate a query for each table like:
DELETE FROM table1 WHERE applicationid = 123 OR schoolid = 123
And it will only include the fields within the tables...
THere's no such single statement.
You could fetch a list of table names from information_schema database, and then use stored procedure or external script to loop through it and delete these rows.
Here's reference about information_schema tables.
http://dev.mysql.com/doc/refman/5.0/en/information-schema.html
First use SHOW TABLES to get list of tables then loop through tables list and use DELETE FROM tablename WHERE field=?
IMPORTANT: You should have privileges to use SHOW TABLES
how is
$showtablequery = "
SHOW TABLES
FROM
[database]
";
$x='0';
$showtablequery_result = mysql_query($showtablequery);
while($r = mysql_fetch_array($showtablequery_result))
{
$query="DELETE FROM $r[$x]
WHERE applicationid = 123 OR schoolid = 123 OR familyid = 123";
$x++
}