[英]Is it possible to select only columns where at least one value is present?
我需要选择所有存在至少一个值的同语。 例如,如果这是我的表:
----------------------------
name | keyword | zip
----------------------------
User1 | test | ""
User2 | test | ""
User3 | "" | ""
应该输出如下内容:
-----------------
name | keyword
-----------------
User1 | test
User2 | test
User3 | ""
问题是zip可能不会为空,在这种情况下,输出还应该包括zip列。 我需要此功能的实际表具有许多可能为空的列。
我尝试使用SELECT * FROM myTable HAVING COUNT(*) > 0
但是不起作用(仍然显示空列)。
还尝试使用php使用循环来解决它,但是也没有达到那种程度。
是否有可能使用SQL这样的事情,还是应该例如使用php完成?
这是我使用此问题的建议在PHP中想到的解决方案。
$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."'";
这将输出以下sql查询: SELECT name, keyword FROM myTable WHERE id = 'postedId'
请注意,select中缺少zip
,这是因为对于该特定查询,zip中没有任何值。 在$stack
数组中,您可以放入要检查的任何列。
还要记下我是如何使用!= ''
检查空值的,但是如果您的表具有空值作为NULL
确保使用IS NOT NULL
代替。
这是很痛苦的,并且不是真正的SQL精神-在select
语句编写语句时, select
语句具有固定数量的列。
也就是说,您可以使用两种级别的动态SQL,一种用于获取列,一种用于使用它们:
-- 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;
注意:在实际的应用程序中,您需要取消分配准备好的语句。
这是说明此过程的db <>小提琴。
这不是一个真正的答案。
这只是如何在Oracle中完成的一个示例(我对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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.