[在线]如何构造 sql 反选语句?

phnessu4 2009-04-22 03:44:43
假设现在有表a 50个字段 1,2,3,4.....50
全选为 select * from `a`

现在不想选第48个字段的信息
而我又不想写 select 1,2,3,4,5...(没有48)..50 from `a`

有什么办法?有没有啥语法?



google都不知道该咋搜啥.....囧zzzz
...全文
860 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
shexingshenxiang 2011-08-05
  • 打赏
  • 举报
回复
已知一个表如下:
ID 姓名 性别 年级 语文 数学 英语。。。。。。。。
1 张三 男 高一 80 90 90 。。。。。。。

通过查询得到
语文 数学 英语。。。。。。。。。。
80 90 90 。。。。。。。。。。

也就是用户不想查询前面的 “ID 姓名 性别 年级” 这4列。
但是后面的所有列又都要

用户也不希望 SELECT 语文, 数学,英语, ... 后面所有的列名 FROM 表

这个只排除某些列以外,其他的列都检索的,只有去查数据字典表,拼动态SQL来处理了。

下面是一个演示的例子:

(SQL Server 2005 Express 下测试通过)

CREATE TABLE TestABC (
[ID] INT,
[姓名] VARCHAR(10),
[性别] CHAR(2),
[年级] CHAR(4),
[语文] INT,
[数学] INT,
[英语] INT,
[物理] INT,
[化学] INT
);

INSERT INTO TestABC
VALUES(1, '张三', '男', '高一', 80, 90, 90, 95, 90);


-- 这个SQL,是除了 'ID', '姓名', '性别', '年级' 这4列以外,其他都检索。
DECLARE @sql VARCHAR(200);
BEGIN
SET @sql =
'SELECT ' + STUFF(
(SELECT
',' + col.name
FROM
sys.columns col
WHERE
col.object_id =
(SELECT object_id FROM sys.tables WHERE name = 'TestAbc')
AND col.name NOT IN ('ID', '姓名', '性别', '年级')
FOR XML PATH('')), 1 , 1, '') + ' FROM TestAbc';
EXECUTE (@sql);
END



-- 这个SQL,是排除前面4列,从第5列开始全部检索。
DECLARE @sql VARCHAR(200);
BEGIN
SET @sql =
'SELECT ' + STUFF(
(SELECT
',' + col.name
FROM
sys.columns col
WHERE
col.object_id =
(SELECT object_id FROM sys.tables WHERE name = 'TestAbc')
AND col.column_id > 4
FOR XML PATH('')), 1 , 1, '') + ' FROM TestAbc';
EXECUTE (@sql);
END


2个SQL 的结果是一样的:

语文 数学 英语 物理 化学
----------- ----------- ----------- ----------- -----------
80 90 90 95 90

(1 行受影响)


http://hi.baidu.com/wangzhiqing999/blog/item/394c5ff831981b96b801a077.html
faisun 2009-04-23
  • 打赏
  • 举报
回复
select *,null as `48` from a where ...
这样行不行啊
phnessu4 2009-04-23
  • 打赏
  • 举报
回复
-_-!

21楼的表名我写错了...
应该是'select * from `c` limit 1'
phnessu4 2009-04-23
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 faisun 的回复:]
select *,null as `48` from a where ...
这样行不行啊
[/Quote]
单条查询的时候,会新建一个字段为`48`下面的数据都为NULL,可以distinct掉,但是旧的`48` 依旧存在,会出现重复字段

.....

快了...离目标不远了..

加分....
phnessu4 2009-04-23
  • 打赏
  • 举报
回复 1
[Quote=引用 16 楼 runffer_yang 的回复:]
用PHP动态生成SQL吧:

PHP code<?php
$res = mysql_query('select * from `a` limit 1', $link);
$field_names = array();
for ($i=0; $i<50; $i++)
{
if ($i!=47)
$field_names[] = mysql_field_name($res, $i);
}

$f_names = implode(",",$filed_names);
$SQL =<<EOT
select distinct $f_names
from
`a` natural join `b` natural join `c`
where
`a`.`1` = `c`.`1` and `a`.`2` = xxx
EOT
?>
[/Quote]

除了视图,这是第二方案,动态生成sql....

在runffer_yang提供的代码基础上,我又加入了字段验证...


//link DB
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASS);
$link = mysql_select_db(DB_NAME,$conn);

//查一条数据
$r = mysql_query('select * from `userreg` limit 1');
//获得表单名数量
$count = count(mysql_fetch_assoc($r));
for($i=0;$i<$count;$i++){
$tmp_name = mysql_field_name($r,$i);
//过滤掉c.shit
if($tmp_name != "c.shit"){
$filed_names[]= mysql_field_name($r,$i);
}
}
$f_names = implode(",",$filed_names);
$sql =<<<EOT
select distinct $f_names
from
`a` natural join `b` natural join `c`
where
`a`.`1` = `c`.`1` and `a`.`2` = xxx
EOT;
//n个字段的sql诞生了
print_r($sql);


其实我想要sql....不是一堆php....-_-#
Steve 2009-04-22
  • 打赏
  • 举报
回复
最后一个EOT少个;
Steve 2009-04-22
  • 打赏
  • 举报
回复
用PHP动态生成SQL吧:
<?php
$res = mysql_query('select * from `a` limit 1', $link);
$field_names = array();
for ($i=0; $i<50; $i++)
{
if ($i!=47)
$field_names[] = mysql_field_name($res, $i);
}

$f_names = implode(",",$filed_names);
$SQL =<<EOT
select distinct $f_names
from
`a` natural join `b` natural join `c`
where
`a`.`1` = `c`.`1` and `a`.`2` = xxx
EOT
?>
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 runffer_yang 的回复:]
人家说的是字段,别误解是记录。
解决方法当然有,不过比你直接写还麻烦。
从系统表里查这个表的所有字段名然后去掉你不要的。
[/Quote]

-_-#

给个指点吧....
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
额...刚刚想到一个嵌套查询...测试了一下...
结果是0条
因为c.shit是包含在c里面的,只要c.shit的not in不匹配,c表一条数据都不会过,natural join不出来

大家继续....我加分....

select distinct * 
from
`a` natural join `b` natural join `c`
where
`a`.`1` = `c`.`1` and `a`.`2` = xxx
and
c.shit not in (select c.shit from c)
Steve 2009-04-22
  • 打赏
  • 举报
回复
人家说的是字段,别误解是记录。
解决方法当然有,不过比你直接写还麻烦。
从系统表里查这个表的所有字段名然后去掉你不要的。

phnessu4 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 yanhuajin 的回复:]

select * from a where id not in (40,38)
=
select * from a where id!=40 and id!=38
[/Quote]
问题是(40,38)这里面的数据是随机的...
yanhuajin 2009-04-22
  • 打赏
  • 举报
回复

select * from a where id not in (40,38)
=
select * from a where id!=40 and id!=38
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 yanhuajin 的回复:]
select * from a where id <>48
如果是几个的话
select * from a where id not in (40,38)
[/Quote]

select * from a where id not in (40,38)
这个的意思是?
小的不才,没看懂...
yanhuajin 2009-04-22
  • 打赏
  • 举报
回复
select * from a where id<>48
如果是几个的话
select * from a where id not in (40,38)
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 jinliangonline 的回复:]
引用 6 楼 phnessu4 的回复:
引用 3 楼 jinliangonline 的回复:
晕,你读出来不用不就完了。
如果你非要这么做,那就建个视图,不包含这个字段。
然后可以直接select * from v_table

如果不建视图..没法解决么?

或许有吧,我不清楚。呵呵。很诚实吧……
[/Quote]

-_-#
jinliangonline 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 phnessu4 的回复:]
引用 3 楼 jinliangonline 的回复:
晕,你读出来不用不就完了。
如果你非要这么做,那就建个视图,不包含这个字段。
然后可以直接select * from v_table

如果不建视图..没法解决么?
[/Quote]
或许有吧,我不清楚。呵呵。很诚实吧……
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 jinliangonline 的回复:]
晕,你读出来不用不就完了。
如果你非要这么做,那就建个视图,不包含这个字段。
然后可以直接select * from v_table
[/Quote]
如果不建视图..没法解决么?
duwenqi1988 2009-04-22
  • 打赏
  • 举报
回复
考虑中,,,,
phnessu4 2009-04-22
  • 打赏
  • 举报
回复
其实这语句本来很麻烦, 我只是为了简化一下问题复杂度才这么问的...

原语句和结构:

a,b,c 三表 字段名(不规则,无法用数学运算判断),字段数各不同

select distinct * 
from
`a` natural join `b` natural join `c`
where
`a`.`1` = `c`.`1` and `a`.`2` = xxx


因为c中有一个字段是老鼠屎c.shit distinct后,其余数据会重复..所以我就想不选这个字段,只选其他的...
jinliangonline 2009-04-22
  • 打赏
  • 举报
回复
晕,你读出来不用不就完了。
如果你非要这么做,那就建个视图,不包含这个字段。
然后可以直接select * from v_table
加载更多回复(2)

21,886

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧