Select on empty table but still get column names - php

I want to do a SELECT on an empty table, but i still want to get a single record back with all the column names. I know there are other ways to get the column names from a table, but i want to know if it's possible with some sort of SELECT query.
I know this one works when i run it directly in MySQL:
SELECT * FROM cf_pagetree_elements WHERE 1=0;
But i'm using PHP + PDO (FETCH_CLASS). This just gives me an empty object back instead of an row with all the column names (with empty values). So for some reason that query doesn't work with PDO FETCH_CLASS.
$stmt = $this->db->prepare ( $sql );
$stmt->execute ( $bindings );
$result = $stmt->fetchAll ( \PDO::FETCH_CLASS, $class );
print_r($result); // Empty object... I need an object with column names
Anyone any idea if there's another method that i can try?

Adding on to what w00 answered, there's a solution that doesn't even need a dummy table
SELECT tbl.*
FROM (SELECT 1) AS ignore_me
LEFT JOIN your_table AS tbl
ON 1 = 1
LIMIT 1
In MySQL you can change WHERE 1 = 1 to just WHERE 1

To the other answers who posted about SHOW COLUMNS and the information scheme.
The OP clearly said: "I know there are other ways to get the column names from a table, but i want to know if it's possible with some sort of SELECT query."
Learn to read.
Anyway, to answer your question; No you can't. You cannot select a row from an empty table. Not even a row with empty values, from an empty table.
There is however a trick you can apply to do this.
Create an additional table called 'dummy' with just one column and one row in it:
Table: dummy
dummy_id: 1
That's all. Now you can do a select statement like this:
SELECT * FROM dummy LEFT OUTER JOIN your_table ON 1=1
This will always return one row. It does however contain the 'dummy_id' column too. You can however just ignore that ofcourse and do with the (empty) data what ever you like.
So again, this is just a trick to do it with a SELECT statement. There's no default way to get this done.

SHOW COLUMNS FROM cf_pagetree_elements;
This will give a result set explaining the table structure. You can quite easily parse the result with PHP.
Another method is to query the infomrmation schema table:
SELECT column_name FROM information_schema.columns WHERE table_name='cf_pagetree_elements';
Not really recommended though!

You could try:
SELECT * FROM information_schema.columns
WHERE table_name = "cf_pagetree_elements"
Not sure about your specific PHP+PDO approach (there may be complications), but that's the standard way to fetch column headings (field names).

this will list the columns of ANY query for PDO drivers that support getColumMeta. I am using this with SQL server and works fine even on very complex queries with aliased tables, sub-queries and unions. Gives me columns even when results are zero
<?php
// just an example of an empty query.
$query =$PDOdb->query("SELECT * from something where 1=0; ");
for ($i=0; $i<$query->columnCount(); $i++) {
echo $query->getColumnMeta($i)['name']."<br />";
}
?>

Even without PDO in the way, the database won't return the structure without at least one row. You could do this and ignore the data row:
SELECT * FROM cf_pagetree_elements LIMIT 1;
Or you could simply
DESC cf_pagetree_elements;
and deal with one row per field.
WHERE 1=0 does not work for me. It always returns empty set.

The latest PDO for SQLSVR definitely works with get column meta.
Simply set up your statement and use this to get an array of useful information:
$stmt->execute();
$meta= array();
foreach(range(0, $stmt->columnCount() - 1) as $column_index)
{
array_push($meta,$stmt->getColumnMeta($column_index));
}

Complete solution for Oracle or MySQL
for any or some columns (my goal is to get arbitrary columns exactly as they are in DB regardless of case)
for any table (w or w/o rows)
$qr = <<<SQL
SELECT $cols
FROM (SELECT NULL FROM DUAL)
LEFT JOIN $able t ON 1 = 0
SQL;
$columns = array_keys($con->query($qr)->fetchAll(PDO::FETCH_ASSOC)[0]);
if($cols === "*") {
array_shift($columns);
}

YOu could use MetaData with;
$cols = mysql_query("SHOW COLUMNS FROM $tableName", $conn);

Related

how to get two rows from sql database

I have a table in sql database named releases this table has 2 rows with the same id like (260) now I would like to get this two rows into my php file I used this function (mysqli_fetch_assoc) but the output gives one single row only (in array) and didn't give me the other one. So how can I get the two rows with array and how to call specific record from this array ???
Here is my code:
$conn = mysqli_query($db,"SELECT * FROM ps4_media_releases_ref LEFT JOIN ps4_releases ON ps4_media_releases_ref.rid=ps4_releases.release_id
WHERE mid = {$media_id2}");
$result=mysqli_fetch_assoc($conn);
$result2=mysqli_num_rows($conn);
Possible solution is (irrespective of technology, modify according to technology)
SELECT column_name(s)
FROM table_name
WHERE ROWNUM <= number;
example
SELECT *
FROM Persons
WHERE ROWNUM <=2;
I am sure there is nothing wrong with php code you have written.
The problem is with query.
Just run your query in my sql client and double confirm that it returns two rows.
Note:
In Doubt double check the count of the associative array returned
echo count($result)
-- Update
mysql_fetch_assoc
will return one row at a time till it returns all the row
so try below code snippet
while ($row = mysql_fetch_assoc($result)) {
echo $row["RecordName or ColumnName"];
///Get as many records as you want
}

Insert Records All At Once

I have a table that has been functional and i added a column to the table. After adding the column i want to add the result of a query (query is same for all but different results) into that column all at once instead of one at a time which will be time consuming. How can i achieve that? Cos after updating, i have just one result in all the column, i cannot use a where clause cos it will require me doing it one after the other
$stmt = $pdo->prepare("UPDATE table SET my_value = '$myValue' ");
$stmt->execute();
UPDATE table
SET my_value = (select col from some_table where ...)
If the value is the same for all rows, I would advise using cross join:
update table t cross join
(select newval . . .) x
set t.col = x.newval;
Note: this is better than a subquery, because the subquery is guaranteed to be evaluated only once.
If you are trying to say that the value is the same for groups of columns, then extend this to a join:
update table t join
(select grp, newval . . .) x
on t.grp = x.grp
set t.col = x.newval;
After adding the column I want to add the result of a query (query
result is same for all) into that column all at once instead of one at
a time which will be time consuming.
The solution depends on what you mean by "Is the same for all the rows."
If you have one value that is exactly the same for all columns, you can just ask for it and then update. This is usually faster (and allows you to debug more easily) than using pure SQL to achieve everything.
If, on the other hand, you mean the values of that column are retrieved by the same query, but will be different for different rows, then a subquery or a cross join as Gordon suggested will do the trick.

Problems with querying when a value is null

I am using php to query a database for one piece of information from each of 10 separate tables currently. The problem with using multiple queries is that it is extremely slow when accessing the web page that uses all of this information. I cannot seem to get all of the information back that I am wanting when one of the values does not exist due to the WHERE... statement.
For instance, my single queries are all in this format:
SELECT eval_id FROM eval WHERE user_id = $id;
My multiple table query looks like this:
SELECT eval_id,list_id,tab_id
FROM eval,list,tab
WHERE eval.user_id = $id
AND list.user_id = $id
AND tab.user_id = $id;
I tried to combine these queries into one large query, but when the user_id of one does not exist in the table, the comparison in the WHERE... statement screws up the entire query. Does anyone know the best way to retrieve all of this information?
Assume that the tables are "eval, list, and tab," and their id's are *_id respectively. What would be the best way to query this even if eval does not contain a result where the user_id = $id?
SELECT eval.eval_id, list.list_id
FROM user
JOIN eval ON eval.user_id = user.id
JOIN list ON list.user_id = user.id
WHERE user.id = $id
Hope it can help you.
Update: Just think about other solution:
SELECT eval_id as id, "eval" as table
FROM eval WHERE eval.user_id = $id
UNION
SELECT list_id as id, "list" as table
FROM list WHERE list.user_id = $id
You could use either of the following to your query in the WHERE statement:
AND TABLE.TABLE_id <> null //null
AND TABLE.TABLE_id <> 'null' //String null
AND TABLE.TABLE_id <> '' //empty String
Check your database to see what kind of empty value your id is returning and choose the addition that matches it.
Also, while LEFT JOINs may be better looking in a query, they are not always faster so make sure you test it before using.

Fetch a particular list from table and fetch the remaining afterwards, using MySQL

This is the complicated query I have ever thought about. I know this will be the one more silly questions.
I have an array of id's which has more than 100 id's inside it. I want to fetch everything from the database, but first the list that equals to id and afterwards I want the remaining.
My attempt:
PHP:
$arr = array(3,1,4);
sort($arr)
$implodedArr = implode(" || id = ", $arr);
Mysql:
SELECT * FROM tablename WHERE id = implodedArr;
I don't think whatever I am doing is right.
Try this. The strategy first is to use the IN operator, rather than lots of concatenated OR statements - this should be faster. We can then use UNION to merge in the ones that don't appear in the first set.
I've marked the found set has having a virtual column of "important=1", for sorting purposes, but you can change this to something more meaningful if you like.
PHP:
$arr = array(3,1,4);
sort($arr)
$implodedArr = implode(",", $arr);
MySQL:
SELECT
*, 1 AS important FROM tablename WHERE id IN ($implodedArray)
UNION
SELECT
*, 0 AS important FROM tablename WHERE id NOT IN ($implodedArray)
ORDER BY
/* You can order by other fields after "important" if you wish */
important DESC;

Filtering SQL Queries Using PHP

I have been searching for a while on a way to select certain columns (fields) in SQL.
What I am trying to do is this... Lets say I have a table with 200 columns of data. I want to select an entire row but only the last 197 columns of data. Leaving out the first 3 columns that have dates and ID's.
It would be very time consuming to type out the 197 field names I wanted the data from. There has to be some easier way of doing it.
Any help or suggestions to point me in the correct direction?
If you are using MySQL, try something like this:
<?php
$query = "
SHOW COLUMNS FROM `Table`
WHERE `Field` NOT LIKE 'rowtoignore1'
AND `Field` NOT LIKE 'rowtoignore2'
AND `Field` NOT LIKE 'rowtoignore3'
";
$r = mysql_query($query) or die(mysql_error());
$queryfields = "";
while($f = mysql_fetch_assoc($r)) {
$queryfields .= "`{$f['Field']}`,";
}
$queryfields = substr($queryfields,0,strlen($queryfields)-1);
$query = "SELECT {$queryfields} FROM `Table` WHERE xyz";
?>
If you're using MySQL you can query the schema to get a column name by index, so you could use an iterative PHP routine to build your query, but it would require 197 select statements before you could run the one you really want. Messy and inefficient.
It seems simpler to do a SELECT * and then ignore the first three columns. If you use mysql_fetch_assoc() you can get the columns you want easily. Take a look at:
http://php.net/manual/en/function.mysql-fetch-array.php
If i am doing this task, i won't exclude the first 3 columns . If the 3 columns contains lengthy text / blob , then you could avoid, else better fetch those 200 columns .
Using this function mysql_list_fields() fetch fields corresponding to a table , and customize the select query to include required fields

Categories