I can't seem to find or write a sqlquery that SELECTS the DEFAULT VALUE
(and I don't think I can generate it in phpmyadmin for me to copy)
I tried to SELECT it as if it was a record but to no avail...
$defaultValue_find = mysql_query(
"SELECT $group FROM grouptable WHERE $group='DEFAULT'")
or die("Query failed:".mysql_error());
$defaultValue_fetch = mysql_fetch_row($defaultValue_find);
$defaultValue = $defaultValue_fetch[0];
echo $defaultValue;
"SELECT $group FROM grouptable WHERE $group=DEFAULT( $group ) "
Or I think better:
"SELECT DEFAULT( $group ) FROM grouptable LIMIT 1 "
Update - correction
As #Jeff Caron pointed, the above will only work if there is at least 1 row in grouptable. If you want the result even if the grouptable has no rows, you can use this:
"SELECT DEFAULT( $group )
FROM (SELECT 1) AS dummy
LEFT JOIN grouptable
ON True
LIMIT 1 ;"
Get the default values of all fields in mytable in the associative array $res:
// MySQL v.5.7+
$res = [];
$sql = "SHOW FULL COLUMNS FROM `mytable`";
foreach ($PDO->query( $sql, PDO::FETCH_ASSOC ) as $row) {
$res[$row['Field']] = $row['Default'] ;
}
print_r($res);
You can get the default column of any table, and in fact lots of interesting information about it, by looking at the INFORMATION_SCHEMA.COLUMNS tables. As the documentation states...
INFORMATION_SCHEMA provides access to database metadata, information about the MySQL server such as the name of a database or table, the data type of a column, or access privileges. (Source: MySQL 8.0 Reference Manual / INFORMATION_SCHEMA Tables / Introduction.)
So, to get the column default, just SELECT COLUMN_DEFAULT, like...
SELECT COLUMN_DEFAULT
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'YourSchema'
AND TABLE_NAME = 'YourTable' AND
COLUMN_NAME = 'YourField';
You can then just wrap this into a subquery, SELECT * FROM YourTable WHERE YourField = (queryabove). This lets you make a much more customizable, default-based list in your MySQL query.
Related
How is it possible to select the first column in the Where clause. I am trying to make a php function to retrieve table data based on the id, yet since the titles of the id columns are different in various tables, I need to refer to the first column in the Where clause as the first column is always the id column.
The scenario would be something like the following, but it throws errors and says that there is an error in the SQL syntax.
$stmt = $this->conn->prepare("SELECT * FROM $table WHERE column(1) = :id");
Thanks in advance.
I don't think there's a built-in way to do this. But you can query INFORMATION_SCHEMA.COLUMNS to get the column names.
$col_stmt = $this->conn->prepare("
SELECT column_name
FROM information_schema.columns
WHERE table_schema = DATABASE()
AND ordinal_position = 1
AND table_name = :table");
$col_stmt->execute([':table' => $table]);
$first_col = $col_stmt->fetchColumn();
$stmt = $this->conn->prepare("SELECT * FROM `$table` WHERE `$first_col` = :id");
Since there is no built-in way to do this, I came up with the following code block to get the first column and then use it in my SELECT statements.
$stmt = $this->conn->query("SHOW columns FROM $table");
return $stmt->fetch(PDO::FETCH_LAZY)[0];
I think this strategy is a bit shorter than Barmar's, though his is completely right and to the point.
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
Hi i have a table in mysql database which has columns like UI_12-Apr-2016,DA_12-Apr-2016.
----------------------------------------------------------------------
| DA_12-Apr-2016 | UI_13-Apr-2016 | UI_12-Apr-2016 | DA_13-Apr-2016 |
|---------------------------------------------------------------------
| |
----------------------------------------------------------------------
How do i fetch data from the table whose columns have 12-Apr-2016 in it. Is there any way to select data according to the criteria. I know i can run this query:-
SELECT UI_12-Apr-2016,DA_12-Apr-2016 from table;
but the date and the code before it can be anything. I want to create a dynamic query to fetch data from the columns that match the date criteria.
I would be highly grateful if anyone can please provide a solution to do it.
This may help:
select COLUMN_name
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME='Table1' and column_name like "%12-Apr-2016%";
in the above query, we can search for column names from INFORMATION_SCHEMA.COLUMNS table(which holds data related to table specified).
Output of above query should:
UI_12-Apr-2016
DA_12-Apr-2016
The result of above query is a list of columns with the pattern given(%12-Apr-2016%). You may save this result in a list and use it to fetch data accordingly from the table.
There is no direct method or query to do the same.
maybe you can create a new table tbl_column with one column column_name include all your columns~
SELECT * FROM tbl_column WHERE column_name LIKE '%12-Apr-2016%';
then you can use the query result to generate a new dynamic sql~
Did you mean:
SELECT * FROM table WHERE column LIKE '%13-Apr-2016%';
?
Update: you should look into information_schema database:
SELECT COLUMN_NAME from `COLUMNS` where `TABLE_NAME` = 'table_name' AND `COLUMN_NAME` LIKE '%12-Apr-2016%';
Simple PHP example script could be:
$table_name = 'table_name';
$col_pattern = '12-Apr-2016';
$mysqli = new mysqli($config['host'], $config['user'], $config['password'], $config['dbname']);
$sql1 = "SELECT COLUMN_NAME from `COLUMNS` where `TABLE_NAME` = '{$table_name}' AND `COLUMN_NAME` LIKE '%{$col_pattern}%'";
$res1 = $mysqli->query($sql1);
$acol = array();
while ($r1 = $res1->fetch_assoc()) {
$acol[] = $r1['COLUMN_NAME'];
}
if (!empty($acol)) {
$sql2 = 'SELECT ' . implode(', ', $acol) . ' FROM ' . $table_name;
$res2 = $mysqli->query($sql2);
while ($r2 = $res2->fetch_assoc()) {
echo var_export($r2, 1) . PHP_EOL;
}
}
You must put together your SQL statement dynamically. E.g. the following statement uses the Oracle view ALL_TAB_COLUMNS to produce a select column_name from table_name statement for every column that contains 12-Apr-2016:
SELECT 'SELECT ' || COLUMN_NAME || ' FROM ' || TABLE_NAME || ';'
FROM ALL_TAB_COLUMNS
WHERE TABLE_NAME = 'MY_TABLE'
AND COLUMN_NAME LIKE '%12-Apr-2016%'
This may not be exactly what you want, however, this illustrates the general idea.
It is not possible to dynamically come up with names of columns since MySQL does not have an eval() function. Since you are using PHP, it is preferable to construct the query from your application in order to achieve this.
If you really insist for a solution using MySQL, there is one using prepared statements that is not too hard to come up with as follows:
set #table='your_table_name';
select group_concat(column_name)
from information_schema.columns
where table_name='your_table_name'
and column_name like '%12_Apr_2016'
into #colnames;
set #construct= CONCAT('SELECT ', #colnames, ' FROM ', #table);
prepare query from #construct;
execute query;
SQL Fiddle for reference.
But overall, having columns named using dynamically generated DDL is not the best schema modeling practice.
i want to check a database and get all table names first and then
show some kind of report from data inside each table
$query = $db3->query("SELECT `table_name` from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db3' ") or die("$db3->error");
while ( $table = $query->fetch_assoc() )
{
//echo $table['table_name'].'<br />';
$t = trim($table['table_name']);
//i get all table names now i want to select all columns from that table name :
$select = $db3->query("SELECT * FROM ".$t." ") or die($db3->error);
$row = $select->fetch_assoc();
// checking to see if query worked fine
echo gettype($row);
//it returns NULL
}
am i doing it the right way ?
what should i do ?
For security reasons you should have a whitelist of databases/tables you want to generate reports from. Querying for all tables assumes that all future tables will need to be part of this system.
You can query for the columns in each table using show columns from tableName and iterate the results.
You can use this query in mysql
mysql> SELECT table_name, table_type, engine
-> FROM information_schema.tables
-> WHERE table_schema = 'db5'
-> ORDER BY table_name DESC;
SELECT table_name, column_name FROM Information_schema.columns WHERE table_name like '%example%' ORDER BY table_name DESC
Or you can try this
SELECT table_name, column_name FROM Information_schema.columns WHERE column_name like '%example%' ORDER BY table_name DESC
I have a MySQL database called "bookfeather." It contains 56 tables. Each table has the following structure:
id site votes_up votes_down
The value for "site" is a book title. The value for "votes_up" is an integer. Sometimes a unique value for "site" appears in more than one table.
For each unique value "site" in the entire database, I would like to sum "votes_up" from all 56 tables. Then I would like to print the top 25 values for "site" ranked by total "votes_up".
How can I do this in PHP?
Thanks in advance,
John
You can do something like this (warning: Extremely poor SQL ahead)
select site, sum(votes_up) votes_up
from (
select site, votes_up from table_1
UNION
select site, votes_up from table_2
UNION
...
UNION
select site, votes_up from table_56
) group by site order by sum(votes_up) desc limit 25
But, as Dav asked, does your data have to be like this? There are much more efficient ways of storing this kind of data.
Edit: You just mentioned in a comment that you expect there to be more than 56 tables in the future -- I would look into MySQL limits on how many tables you can UNION before going forward with this kind of SQL.
Here's a PHP code snip that should get it done.
I have not tested it so it might have some typos and stuff, make sure you replace DB_NAME
$result = mysql_query("SHOW TABLES");
$tables = array();
while ($row = mysql_fetch_assoc($result)) {
$tables[] = '`'.$row["Tables_in_DB_NAME"].'`';
}
$subQuery = "SELECT site, votes_up FROM ".implode(" UNION ALL SELECT site, votes_up FROM ",$tables);
// Create one query that gets the data you need
$sqlStr = "SELECT site, sum(votes_up) sumVotesUp
FROM (
".$subQuery." ) subQuery
GROUP BY site ORDER BY sum(votes_up) DESC LIMIT 25";
$result = mysql_query($sqlStr);
$arr = array();
while ($row = mysql_fetch_assoc($result)) {
$arr[] = $row["site"]." - ".$row["sumVotesUp"];
}
print_r($arr)
The UNION part of Ian Clelland answer can be generated using a statement like the following. The table INFORMATION_SCHEMA.COLUMNS has a column TABLE_NAME to get all tables.
select * from information_schema.columns
where table_schema not like 'informat%'
and column_name like 'VOTES_UP'
Join all inner SELECT with UNION ALL instead of UNION. UNION is doing an implicit DISTINCT (on oracle).
The basic idea would be to iterate over all your tables (using a SQL SHOW TABLES statement or similar) in PHP, then for every table, iterate over the rows (SELECT site,votes_up FROM $table). Then, for every row, check the site against an array that you're building with sites as keys and votes up as values. If the site is already in the array, increment its votes appropriately; otherwise, add it.
Vaguely PHP-like pseudocode:
// Build an empty array for use later
$votes_array = empty_array();
// Get all the tables and iterate over them
$tables = query("SHOW TABLES");
for($table in $tables) {
$rows = query("SELECT site,votes_up FROM $table");
// Iterate over the rows in each table
for($row in $rows) {
$site = $row['site'];
$votes = $row['votes_up'];
// If the site is already in the array, increment votes; otherwise, add it
if(exists_in_array($site, $votes_array)) {
$votes_array[$site] += $votes;
} else {
insert_into_array($site => $votes);
}
}
}
// Get the sites and votes as lists, and print out the top 25
$sorted_sites = array_keys($votes_array);
$sorted_votes = array_values($votes_array);
for($i = 0; $i < 25; $i++) {
print "Site " . $sorted_sites[$i] . " has " . $sorted_votes[$i] . " votes";
}
"I allow users to add tables to the database." - I hope all your users are benevolent and trustworthy and capable. Do you worry about people dropping or truncating tables, creating incorrect new tables that break your code, or other things like that? What kind of security do you have when users can log right into your database and change the schema?
Here's a tutorial on relational database normalization. Maybe it'll help.
Just in case someone else that comes after you wants to find what this could have looked like, here's a single table that could do what you want:
create database bookfeather;
create user bookfeather identified by 'bookfeather';
grant all on bookfeather.* to 'bookfeather'#'%';
use bookfeather;
create table if not exists book
(
id int not null auto_increment,
title varchar(255) not null default '',
upvotes integer not null default 0,
downvotes integer not null default 0,
primary key(id),
unique(title)
);
You'd vote a title up or down with an UPDATE:
update book set upvotes = upvotes + 1 where id = ?
Adding a new book is as easy as adding another row:
insert into book(title) values('grails in action')
I'd strongly urge that you reconsider.