当前位置: 代码迷 >> SQL >> 在论坛中出现的比较难的sql有关问题:6
  详细解决方案

在论坛中出现的比较难的sql有关问题:6

热度:73   发布时间:2016-05-05 11:58:41.0
在论坛中出现的比较难的sql问题:6
最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。

 

1、这个语句怎么写?

http://bbs.csdn.net/topics/390490832?page=1

我有一张表:CarRule
有下面这些列和数据
ID    Keywords
1     时速50%、 不到100%
2     违反禁令标志
3     违反规定停放、拒绝立即驶离、妨碍其他车辆

我要查询这个CarRule表,根据关键字获取ID
例如:机动车行驶超过规定时速50%以上不到100%的  就能获取到  ID=1
      机动车违反禁令标志的                     就能获取到  ID=2
      违反规定停放、临时停车且驾驶人不在现场或驾驶人虽在现场拒绝立即驶离,妨碍其他车辆、行人通行的        
就能获取到  ID=3

这个查询我怎么写。

 

我的解法:

--1.先建立一个函数,通过分隔符来拆分keywords成多个关键字create function dbo.fn_splitSTR(	@s varchar(8000),     --要分拆的字符串	@split varchar(10)    --分隔字符) returns @re table(                      --要返回的临时表                     col varchar(1000)  --临时表中的列                  )asbegin     declare @len int    set @len = LEN(@split)      --分隔符不一定就是一个字符,可能是2个字符    while CHARINDEX(@split,@s) >0  begin	insert into @re 	values(left(@s,charindex(@split,@s) - 1))		set @s = STUFF(@s,1,charindex(@split,@s) - 1 + @len ,'')    --覆盖:字符串以及分隔符  end    insert into @re values(@s)    return   --返回临时表endgo  --2.建表DECLARE @CarRule TABLE(id INT,Keywords VARCHAR(100))INSERT INTO @carruleVALUES(1,'时速50%、不到100%'),      (2,'违反禁令标志'),      (3,'违反规定停放、拒绝立即驶离、妨碍其他车辆');WITH split  --拆分关键字as(SELECT  c.id,        c.keywords,        f.col  FROM @carrule cCROSS apply dbo.fn_splitSTR(c.keywords,'、') f)--3.第1个查询SELECT s.id,       s.keywordsFROM split sINNER JOIN 		(			SELECT s.id,			       s.keywords,			       count(col) AS split_str_count   --拆分成了几个关键字			FROM split s			GROUP BY s.id,			         s.keywords				) ss        ON s.id = ss.idWHERE charindex(s.col,'机动车行驶超过规定时速50%以上不到100%的') > 0GROUP BY s.id,         s.keywordsHAVING count(*) = max(ss.split_str_count)  --比如第一条记录拆分成了2个关键词,那么在匹配时要2个都匹配上了,才算为匹配


第2个查询:

DECLARE @CarRule TABLE(id INT,Keywords VARCHAR(100))INSERT INTO @carruleVALUES(1,'时速50%、不到100%'),      (2,'违反禁令标志'),      (3,'违反规定停放、拒绝立即驶离、妨碍其他车辆');WITH split  --拆分关键字as(SELECT  c.id,        c.keywords,        f.col  FROM @carrule cCROSS apply dbo.fn_splitSTR(c.keywords,'、') f)--3.SELECT s.id,       s.keywordsFROM split sINNER JOIN 		(			SELECT s.id,			       s.keywords,			       count(col) AS split_str_count   --拆分成了几个关键字			FROM split s			GROUP BY s.id,			         s.keywords				) ss        ON s.id = ss.idWHERE charindex(s.col,'机动车违反禁令标志的') > 0GROUP BY s.id,         s.keywordsHAVING count(*) = max(ss.split_str_count)  --比如第一条记录拆分成了2个关键词,那么在匹配时要2个都匹配上了,才算为匹配


第3个查询:

DECLARE @CarRule TABLE(id INT,Keywords VARCHAR(100))INSERT INTO @carruleVALUES(1,'时速50%、不到100%'),      (2,'违反禁令标志'),      (3,'违反规定停放、拒绝立即驶离、妨碍其他车辆');WITH split  --拆分关键字as(SELECT  c.id,        c.keywords,        f.col  FROM @carrule cCROSS apply dbo.fn_splitSTR(c.keywords,'、') f)--3.SELECT s.id,       s.keywordsFROM split sINNER JOIN 		(			SELECT s.id,			       s.keywords,			       count(col) AS split_str_count   --拆分成了几个关键字			FROM split s			GROUP BY s.id,			         s.keywords				) ss        ON s.id = ss.idWHERE charindex(s.col,'违反规定停放、临时停车且驾驶人不在现场或驾驶人虽在现场拒绝立即驶离,妨碍其他车辆、行人通行的就能获取到') > 0GROUP BY s.id,         s.keywordsHAVING count(*) = max(ss.split_str_count)  --比如第一条记录拆分成了2个关键词,那么在匹配时要2个都匹配上了,才算为匹配

 

2、统一改换查询出的字段。。这是不是想多了?

http://bbs.csdn.net/topics/390610092

能不能这样

select     A.* as A_* 
from QAQuestion Q 
inner join QAAnswer A ON A.QuestionID = Q.ID

简单地说,不想一个个地去给每个字段as别名
我如上去写只是打个比方。。实际运行不了的,想得到的查询结果是
A_字段1,A_字段2,A_字段3,A_字段4

有没有办法呢?

 

我的回复:

本质上来说,只有在sql server端,能把select a.* as a_*,也就是自动进行转换,才能支持。

因为在sql server端,你写的sql语句是各式各样的,要想实现你的A.* as A_*,实际上就是要改写查询,改为:

select a.字段1 as a_字段1,
       a.字段2 as a_字段2,
       a.字段3 as a_字段3,
from a

下面是通过动态语句来实现的:

--先建个表select * into wc_tablefrom sys.objects/*要实现select a.* as a_*from wc_table的效果*/--动态生成语句为:declare @sql varchar(max);set @sql = '';select @sql = @sql + ',' + c.name + ' as A_' + c.name   from sys.tables tinner join sys.columns c        on t.object_id = c.object_idwhere t.name = 'wc_table'order by c.column_idset @sql = 'select ' +            STUFF(@sql,1,1,'') +           ' from wc_table A'select @sql           /*我把结果格式化了一下就是这样:SELECT name                AS A_name,        object_id           AS A_object_id,        principal_id        AS A_principal_id,        schema_id           AS A_schema_id,        parent_object_id    AS A_parent_object_id,        type                AS A_type,        type_desc           AS A_type_desc,        create_date         AS A_create_date,        modify_date         AS A_modify_date,        is_ms_shipped       AS A_is_ms_shipped,        is_published        AS A_is_published,        is_schema_published AS A_is_schema_published FROM   wc_table A  */exec(@sql) 


 

  相关解决方案