How to get column name whose value is not null in mysql - php

I have a table which has a single entry. I have to get those column values whose values are not null. Please suggest me query for MySQL so I can implement this. My table is :
In this table 3 columns have Null values. So I don't want these columns, query should return values which in not null.
Can I get the column name also? Like I want to get name of the column i.e min_p5 whose value is not null. So I can break the column name into strings and use 5 in my calculation. Please suggest me answer.

I think this is what you need:
Assuming your table name to be "orders" [pls change it accordingly]
$q="show columns from orders";
$res=mysql_query($q) or die(mysql_error());
$arr_field=array();
while($row=mysql_fetch_object($res)){
$field=$row->Field;
$q1="select ".$field." from orders where ".$field."!=0"; //if string then '0'
$res1=mysql_query($q1) or die(mysql_error());
if(mysql_num_rows($res1)>0){
$arr_field[]=$field;
}
}
$q="select ";
foreach($arr_field as $field){
$q.=$field.",";
}
$q=rtrim($q,",");
$q.=" from orders";
$res=mysql_query($q) or die(mysql_error());
while($row=mysql_fetch_object($res)){
foreach($arr_field as $field){
print($field."==".$row->$field."<br/>");
}
}
Run this and I hope you will get an idea...

SELECT *
FROM table
WHERE YourColumn IS NOT NULL;
Source: MySQL SELECT only not null values

select * from table where column_name is not null

Try following query for solve your problem,
select * from table
where column_name IS NOT NULL

It seems like you want to return:
| POINT_ID | BUS_ID | MIN_P5 | MIN_P15 |
|----------|--------|--------|---------|
| P101 | B101 | 1000 | 3000 |
because you want to exclude columns that have a zero value. It is not too easy to do this in MySQL because you need to use prepared statements:
SELECT
CONCAT(
'SELECT CONCAT(\'SELECT \',
CONCAT_WS(\',\',',
GROUP_CONCAT(
CONCAT(
'CASE WHEN EXISTS(SELECT * FROM TABLENAME WHERE ',
`column_name`,
'!=\'0\') THEN \'',
`column_name`,
'\' END')
),
'),\' FROM tablename\') FROM tablename INTO #final_sql'
)
FROM `information_schema`.`columns`
WHERE `table_schema`=DATABASE()
AND `table_name`='tablename'
INTO #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
PREPARE finalstmt FROM #final_sql;
EXECUTE finalstmt;
Please see fiddle here. If your columns are numbers and not strings, maybe some minor fixes are needed. However, I would suggest you to try a different approach or to rethink about your table structure.

Related

Is it possible to select only columns where at least one value is present?

I need to select all coulmns where at least one value is present. For example if this is my table:
----------------------------
name | keyword | zip
----------------------------
User1 | test | ""
User2 | test | ""
User3 | "" | ""
Should output something like this:
-----------------
name | keyword
-----------------
User1 | test
User2 | test
User3 | ""
The thing is that zip might not be empty and in this case the output should also include the zip column. The actual table I need this functionality for has many more columns that can potentially be empty.
I tried using SELECT * FROM myTable HAVING COUNT(*) > 0 but that did not work (empty columns were still showing).
Also tried solving it with php using loops but didn't get far that way either.
Is something like this even possible using SQL or should it be done using php for example?
SOLUTION
Here's the solution I came up with in PHP using the suggestions I got for this question.
$stack = array("keyword", "zip");
$id = $_POST["id"];
$sql = "SELECT name";
foreach($stack as $i){
$q = "SELECT ".$i." FROM myTable WHERE ".$i." != '' AND id = '".$id."'";
$result = mysqli_query($link, $q);
if(mysqli_num_rows($result) > 0){
$sql = $sql.", ".$i;
}
}
$sql = $sql." FROM myTable WHERE id = '".$id."'";
This will output the following sql query:
SELECT name, keyword FROM myTable WHERE id = 'postedId'
Notice the zip is missing from select, this is because for that particular query there were no values in zip. In the $stack array you can put whatever columns you want to check.
Also make note of how I used != '' to check for empty values but if your table has empty values as NULL make sure to use IS NOT NULL instead.
This is quite painful and not really in the spirit of SQL -- where a select statement has a fixed number of columns defined when the statement is written.
That said, you can use two levels of dynamic SQL, one to get the columns and one to use them:
-- generate the SQL to identify the columns
select #sql := group_concat(replace('select max(''[column_name]'') as col from t having count([column_name]) > 0', '[column_name]', c.column_name)
separator ' union all ' )
from information_schema.columns c
where table_name = 't';
-- use the SQL to get the columns
select #sql := concat('select group_concat(col separator '', '') into #cols from (', #sql, ') x');
-- run the SQL
prepare s from #sql;
execute s ;
-- create the final query using the columns
set #sql2 = concat('select ', #cols, ' from t');
-- and execute it
prepare s2 from #sql2;
execute s2;
Note: in a real application, you would want to deallocate the prepared statements.
Here is a db<>fiddle illustrating this process.
This is not a the real answer.
Just an example of how it could be done in Oracle (I got very little experience with MySQL):
DECLARE
has_keyword INTEGER;
has_zip INTEGER;
sql VARCHAR2(1024);
BEGIN
-- Determine the columns having at least 1 row with a not null value
SELECT CASE WHEN MAX(keyword) IS NULL THEN 0 ELSE 1 END,
CASE WHEN MAX(zip) IS NULL THEN 0 ELSE 1 END
INTO has_keyword,
has_zip
FROM my_table;
-- Compose query
sql := 'SELECT name';
IF (has_keyword > 0) THEN
sql := sql || ', keyword';
END IF;
IF (zip > 0) THEN
sql := sql || ', zip';
END IF;
sql := sql || ' FROM my_table';
-- Execute query
EXECUTE IMMEDIATE sql;
END;

Mysql order by column when not empty then order by other column

I would like some help that has had me stumped for two days. I need to retrieve data from a database and order it by column1 when it isn't empty and then the rest of the result by column2
column1 column2
1 11
2 12
3 13
14
15
16
Required result
1,2,3,14,15,16
I've tried numerous approaches, my latest failed attempt being
$SQL = "SELECT * FROM table ORDER BY COALESCE(column1, column2) DESC";
and
$SQL = "SELECT * FROM table ORDER BY COALESCE(column1, column2) ASC";
My above SQL is returning NULL value column1 above column2
This should work:
$SQL = "SELECT * FROM table ORDER BY COALESCE(NULLIF(Other,''), column2) DESC";
I saw it here: SQL Coalesce with empty string
coalesce() would only work if the "empty" values in column1 are actually NULL. Empty strings will not trigger a coalesce() operation.
Beyond that, your query will NOT work. You cannot do a select * with two columns and somehow magically get one single column in the result. For this you'll need a UNION query:
(SELECT column1 AS col FROM yourtable)
UNION ALL
(SELECT column2 AS col FROM yourtable)
ORDER BY col
If you want 1 column, you could try a combination of NULLIF and COALESCE, that should account for both empty and null values
SELECT COALESCE(NULLIF(column1, ''), column2) AS COL
FROM table
SQLFiddle Demo
In case you actually want all of the numbers on a single result row, separated by commas, you can use GROUP_CONCAT along with the previous code:
SELECT GROUP_CONCAT(COALESCE(NULLIF(column1, ''), column2)) AS col
FROM table
SQLFiddle Demo2
Old question but this solution worked for me:
$SQL = "SELECT * FROM table ORDER BY COALESCE(NULLIF(column1, ''), column2)";
You should be able to use CASE like so:
SELECT *
FROM table
ORDER BY
CASE WHEN LENGTH(column1) IS >0 THEN column1
ELSE column2 END
ASC
http://dev.mysql.com/doc/refman/5.0/en/case.html

How do you return rows from Mysql based on highest value in table column?

I have a function that is supposed to search the db for the highest 'score'.
The Db is structured like this:
----------------------------------------
| id | UrlId | Article | Score |
----------------------------------------
I can get the highest score correctly, but I do not know how to return the full object based on the highest score.
I am reluctant to loop through the entire table and test the values of 'score' to see which is the highest (although as I type that I suspect I am doing it anyway) because the db will potentially have 10000's of records.
I am sure that this is dead simple, but I have "the dumb and I cant brain today" Does anyone know a more elegant solution?
My end result would have to be something like this:
if there are 4 UrlId;s with the same top score, the user would need to see:
UrlId example1 20(score)
UrlId example2 20(score)
UrlId example3 20(score)
UrlId example4 20(score)
all other results would not be displayed.
function gethappiestBlog() {
$happiestBlogs = /* This is the data that I loop through, this is correct */
$happinessArray = array();
foreach($happiestBlogs as $happiestBlog) {
$happinessArray[]= $happiestBlog->Score;
}
$maxHappy = max($happinessArray);
echo $maxHappy;
}
SELECT fieldlist
FROM `tableName`
WHERE `score` = (SELECT MAX(`score`) FROM `tableName`)
Couldn't you use a query?
SELECT *
FROM table_name
ORDER BY score
DESC LIMIT 1;
If you need multiple scores, you could then use a subquery:
SELECT *
FROM table_name
WHERE score =
(SELECT score
FROM table_name
ORDER BY score
DESC LIMIT 1;
);
Try this.
$dbh=new PDO(DSN,USERNAME,PASSWORD);
$stmt=$dbh->prepare("SELECT * FROM TABLE_NAME ORDER BY Score DESC");
$stmt->execute();
while($happiestBlog=$stmt->fetch(PDO::FETCH_OBJ)):
echo $happiestBlog->Score;
endwhile;
Here ORDER BY Score DESC fetch the the row first ehich has highest Score.

Get column names of multiple tables and insert it to another table + PHP MySQL

I have this code:
$createFields="CREATE TABLE temp_field (fld text NOT NULL, tablename char(50) NOT NULL)";
mysql_query($createFields);
$fields=array();
$campaign=mysql_query("SELECT campaignid FROM campaign ORDER BY campaignid");
while($row=mysql_fetch_array($campaign)){
$table="'campaign_".$row['campaignid']."'";
$temp_field="SELECT COLUMN_NAME,TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=".$table;
$temp_fieldquery = mysql_query($temp_field);
while($rowL=mysql_fetch_array($temp_fieldquery)){
$fields[]="'".$rowL['COLUMN_NAME']."'";
}
$field=implode(",",$fields);
$insertFields='INSERT INTO temp_field (fld,tablename) VALUES ("'.$field.'","'.$table.'")';
mysql_query($insertFields);
and I need to have this kind of output:
fld | tablename
=====================================
fld1,fld2,fld3,fld4... | table1
fld1,fld2,fld3,fld4... | table2
but what I get is:
fld | tablename
========================================================
fld1,fld2,fld3,fld4... | table1
fld1,fld2,fld3,fld4,fld1,fld2,fld3,fld4... | table2
The second table gets the values of first table
What am I doing wrong with my code, please help
Just initialize your $fields array right before the while loop.
$fields = array();
while($rowL=mysql_fetch_array($temp_fieldquery)){
$fields[]="'".$rowL['COLUMN_NAME']."'";
}
$field=implode(",",$fields);
What happened in your code is that the $fields array continues to add new fields for each succeeding table due to $fields[] so resetting to a new array should fix it.
INSERT INTO temp_field
SELECT
GROUP_CONCAT(COLUMN_NAME separator ",") AS fld
TABLE_NAME AS tablename
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME LIKE 'campaign_%'
GROUP BY TABLE_NAME
Your code sample is much to complicated.
Just use the query above.

Sql results into php array

I would like to create an array (in php) from sql results like this:
We have the sql-table "Posts" which stores the Name and the Message.Example:
Name | Message
John | Hello
Nick | nice day
George | Good bye
John | where
What i want is to output the names of people who have posted a message but dont display the same names more than 1 time.
So the output would be John,Nick,George.
(From these records, we see that John has posted 2 messages, but at the final output, we see only one time his name).
Is this somehow possible?
Thanks in advance.
Try:
$sql = <<<END
SELECT DISTINCT Name FROM Posts
END;
$query = mysql_query($sql) or die($sql . ' - ' . mysql_error());
$names = array();
while ($row = mysql_fetch_array($query)) {
$names[] = $row[0];
}
print_r($names);
SELECT DISTINCT
You could run a SQL query to just select the distinct names, and nothing else:
SELECT DISTINCT Name FROM Posts;
This will give you a result set consisting of distinct Names values, with each unique value only being returned 1 time in the set.
to get the count you will need to aggregate using group by:
SELECT
NAME
, COUNT(*) as Posts
FROM
Posts
GROUP BY
NAME
Here is the SQL if you are not averse to group BY
select count(name) as N, name from posts group by name ;
People having more than 1 post
select count(name) as N, name from posts group by name having N > 1 ;

Categories