求一条SQL语句!!

chinaboyzyq 2009-08-04 04:01:53
现有数据表Table1
结构如下:(字段有id为整型自增长主键x1和x2为nvarchar)
id x1 x2
1 aa a1
2 aa a2
3 aa a3
... ... ...
... ... ...
15 bb b1
16 bb b2
17 bb b3
... ... ...
... ... ...
20 cc c1
21 cc c2
22 cc c3
... ... ...
... ... ...

条件:id数据不保证连续,x1和x2字段不保证排序,x1可能还有dd、ee等,有多少种不定。

SQL语句,完成如下功能:
1)按x1分组
2)每组取任意条想要的随机记录,比如aa组取任意2条,bb组取任意3,……
3)最后按id排序
问:
1)不考虑在任何开发语言中组合SQL语句完成任务。
2)在SQL Server 2000 企业管理器中怎么写SQL语句完成任务(所求的SQL语句)。
3)能否用一条SQL语句完成些功能。
4)能否用group by 在一条SQL语句中完成任务




...全文
304 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
yinchuanwang 2009-08-13
  • 打赏
  • 举报
回复


CREATE TABLE TB
(
id int identity(1,1),
x1 nvarchar(10),
x2 nvarchar(10)
)
INSERT INTO TB select
'aa' , 'a1'union all select
'aa', 'a2'union all select
'aa', 'a3'union all select
'bb', 'b1'union all select
'bb', 'b2'union all select
'bb', 'b3'union all select
'cc', 'c1'union all select
'cc', 'c2'union all select
'cc', 'c3'


create table ta(x1 nvarchar(12),num int)
insert ta select
'aa',2 union all select
'bb',1 union all select
'cc',3



declare @count int
declare @maxid int
declare @x1 nvarchar(10)

set @count = 1

select x1, IDENTITY(int,1,1) as id into #tmp from tb group by x1
select @maxid = MAX(id) from #tmp
declare @result table( id int, x1 nvarchar(10), x2 nvarchar(10))
while @count <= @maxid
begin
select @x1 = x1 from #tmp where #tmp.id = @count
insert into @result select * from tb a where a.id in (select top (select num from ta where ta.x1 = @x1) id from tb b where b.x1 = @x1 order by NEWID())
set @count = @count + 1
end
select * from @result
drop table #tmp
/*
id x1 x2
1 aa a1
3 aa a3
5 bb b2
7 cc c1
8 cc c2
9 cc c3
*/
chinaboyzyq 2009-08-13
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 sql77 的回复:]

你有自增列,

SET IDENTITY_INSERT ON 才能显示插入
[/Quote]
DECLARE @ROWS INT --取条数变量
SET @ROWS=2 --按需赋值

CREATE TABLE tmpTable(id int identity(1,1) ,x1 nvarchar(12),x2 nvarchar(12))
insert tmpTable select
'aa' , 'a1'union all select
'aa', 'a2'union all select
'aa', 'a3'union all select
'bb', 'b1'union all select
'bb', 'b2'union all select
'bb', 'b3'union all select
'cc', 'c1'union all select
'cc', 'c2'union all select
'cc', 'c3'

--select * from tmpTable
declare @I int
declare @J int --总分组数
DECLARE @SQL CHAR(4000)
SET @SQL=''
CREATE table BT(id int identity(1,1) ,x1 nvarchar(12))
INSERT INTO BT
select X1 FROM tmpTable GROUP BY X1 ORDER BY X1
SET @J=@@ROWCOUNT
SET @I=1
WHILE @I <=@J --循环组织SQL语句
BEGIN
SET @SQL=RTRIM(@SQL)+' SELECT TOP '+str(@I+@ROWS-1) +' ID,X1,X2,flag='+str(@I)+
' FROM tmpTable WHERE
X1=(SELECT X1 FROM BT WHERE ID='+str(@I)+')'
IF @I <@J
SET @SQL=RTRIM(@SQL)+' UNION ALL '
SET @I=@I+1
CONTINUE
END

SET @SQL='select ID,X1,X2 from ('+RTRIM(@SQL)+') A order by flag,id'
--SELECT Rtrim(@SQL)
exec (@SQL)

DROP TABLE tmpTable
DROP TABLE BT
以上语句怎么改一下呢,谢谢
lavly 2009-08-13
  • 打赏
  • 举报
回复
如果只要一组数据的话 而且也不想用存储过程的话

根据你要的数据aa还是bb还是cc传参
然后用order by读取要的几条

sql语句的组成中字段就是你要的aa还是bb
order by 的top就是你要的几条

多组你就循环传参 然后放在数据集里
gw6328 2009-08-13
  • 打赏
  • 举报
回复
帮顶
SQL77 2009-08-13
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 chinaboyzyq 的回复:]
引用 35 楼 xgj889 的回复:
DECLARE @ROWS INT        --取条数变量
SET @ROWS=2                --按需赋值

CREATE TABLE tmpTable(id int identity(1,1) ,x1 nvarchar(12),x2 nvarchar(12))
insert tmpTable select
'aa' , 'a1'union all select
'aa',  'a2'union all select
'aa',  'a3'union all select
'bb',  'b1'union all select
'bb',  'b2'union all select
'bb',  'b3'union all select
'cc',  'c1'union all select
'cc',  'c2'union all select
'cc',  'c3'

--select * from tmpTable
declare @I int       
declare @J int            --总分组数
DECLARE @SQL CHAR(4000)
SET @SQL=''
CREATE table BT(id int identity(1,1) ,x1 nvarchar(12))
INSERT INTO BT
select X1 FROM tmpTable GROUP BY X1 ORDER BY X1
SET @J=@@ROWCOUNT
SET @I=1
WHILE @I <=@J        --循环组织SQL语句
    BEGIN
        SET @SQL=RTRIM(@SQL)+' SELECT TOP '+str(@I+@ROWS-1) +' ID,X1,X2,flag='+str(@I)+
            ' FROM tmpTable WHERE
            X1=(SELECT X1 FROM BT WHERE ID='+str(@I)+')'
        IF @I <@J
            SET @SQL=RTRIM(@SQL)+' UNION ALL '
        SET @I=@I+1
        CONTINUE
    END

SET @SQL='select  ID,X1,X2 from ('+RTRIM(@SQL)+') A  order by flag,id'
--SELECT Rtrim(@SQL)
exec (@SQL)

DROP TABLE tmpTable
DROP TABLE BT



SQL 查询分析器中出现以下错误为何?
服务器: 消息 8101,级别 16,状态 1,行 22
仅当使用了列的列表,并且 IDENTITY_INSERT 为 ON 时,才能在表 'BT' 中为标识列指定显式值。

[/Quote]
你有自增列,

SET IDENTITY_INSERT ON 才能显示插入
chinaboyzyq 2009-08-13
  • 打赏
  • 举报
回复
[Quote=引用 35 楼 xgj889 的回复:]
DECLARE @ROWS INT --取条数变量
SET @ROWS=2 --按需赋值

CREATE TABLE tmpTable(id int identity(1,1) ,x1 nvarchar(12),x2 nvarchar(12))
insert tmpTable select
'aa' , 'a1'union all select
'aa', 'a2'union all select
'aa', 'a3'union all select
'bb', 'b1'union all select
'bb', 'b2'union all select
'bb', 'b3'union all select
'cc', 'c1'union all select
'cc', 'c2'union all select
'cc', 'c3'

--select * from tmpTable
declare @I int
declare @J int --总分组数
DECLARE @SQL CHAR(4000)
SET @SQL=''
CREATE table BT(id int identity(1,1) ,x1 nvarchar(12))
INSERT INTO BT
select X1 FROM tmpTable GROUP BY X1 ORDER BY X1
SET @J=@@ROWCOUNT
SET @I=1
WHILE @I<=@J --循环组织SQL语句
BEGIN
SET @SQL=RTRIM(@SQL)+' SELECT TOP '+str(@I+@ROWS-1) +' ID,X1,X2,flag='+str(@I)+
' FROM tmpTable WHERE
X1=(SELECT X1 FROM BT WHERE ID='+str(@I)+')'
IF @I<@J
SET @SQL=RTRIM(@SQL)+' UNION ALL '
SET @I=@I+1
CONTINUE
END

SET @SQL='select ID,X1,X2 from ('+RTRIM(@SQL)+') A order by flag,id'
--SELECT Rtrim(@SQL)
exec (@SQL)

DROP TABLE tmpTable
DROP TABLE BT

[/Quote]

SQL 查询分析器中出现以下错误为何?
服务器: 消息 8101,级别 16,状态 1,行 22
仅当使用了列的列表,并且 IDENTITY_INSERT 为 ON 时,才能在表 'BT' 中为标识列指定显式值。
XGJ889 2009-08-13
  • 打赏
  • 举报
回复
知道了,加个参数就好了
chinaboyzyq 2009-08-12
  • 打赏
  • 举报
回复
dd~~
XGJ889 2009-08-12
  • 打赏
  • 举报
回复

DECLARE @ROWS INT --取条数变量
SET @ROWS=2 --按需赋值

CREATE TABLE tmpTable(id int identity(1,1) ,x1 nvarchar(12),x2 nvarchar(12))
insert tmpTable select
'aa' , 'a1'union all select
'aa', 'a2'union all select
'aa', 'a3'union all select
'bb', 'b1'union all select
'bb', 'b2'union all select
'bb', 'b3'union all select
'cc', 'c1'union all select
'cc', 'c2'union all select
'cc', 'c3'

--select * from tmpTable
declare @I int
declare @J int --总分组数
DECLARE @SQL CHAR(4000)
SET @SQL=''
CREATE table BT(id int identity(1,1) ,x1 nvarchar(12))
INSERT INTO BT
select X1 FROM tmpTable GROUP BY X1 ORDER BY X1
SET @J=@@ROWCOUNT
SET @I=1
WHILE @I<=@J --循环组织SQL语句
BEGIN
SET @SQL=RTRIM(@SQL)+' SELECT TOP '+str(@I+@ROWS-1) +' ID,X1,X2,flag='+str(@I)+
' FROM tmpTable WHERE
X1=(SELECT X1 FROM BT WHERE ID='+str(@I)+')'
IF @I<@J
SET @SQL=RTRIM(@SQL)+' UNION ALL '
SET @I=@I+1
CONTINUE
END

SET @SQL='select ID,X1,X2 from ('+RTRIM(@SQL)+') A order by flag,id'
--SELECT Rtrim(@SQL)
exec (@SQL)

DROP TABLE tmpTable
DROP TABLE BT

--执行结果
--------------------------
id x1 x2
1 aa a1
2 aa a2
4 bb b1
5 bb b2
6 bb b3
7 cc c1
8 cc c2
9 cc c3
]
chinaboyzyq 2009-08-08
  • 打赏
  • 举报
回复
zjd~~~~~~~~~~~~
chinaboyzyq 2009-08-07
  • 打赏
  • 举报
回复
zjd~~~~
geto1080 2009-08-06
  • 打赏
  • 举报
回复
顶一下!
chinaboyzyq 2009-08-05
  • 打赏
  • 举报
回复
[Quote=引用 28 楼 js_szy 的回复:]
-- 经过我向大侠们请教之后,总结了3个方法,但都是SQL2005的

--1、
;with t as
(
select rn=row_number()over(partition by x1 order by newid()),*
from ta
)
select t.id,t.x1,t.x2
from t
join tb
on t.rn<=tb.num and t.x1=tb.x1
--2、
;with liang as
(
select a.x1,a.x2,b.num,
id=row_number() over(partition by a.x1 order by newid())
from ta as a join tb as b
on a.x1=b.x1
)
select x1,x2,id from liang
where id <=num;
--3、
select o.*
from tb cross apply (select top(tb.num) * from ta where ta.x1=tb.x1 order by newid()) o
[/Quote]

看样子不错,但都不能在2000下运行
2000下怎么做呢?~~~~
华夏小卒 2009-08-04
  • 打赏
  • 举报
回复

-- 经过我向大侠们请教之后,总结了3个方法,但都是SQL2005的

if object_id('ta')is not null drop table ta
create table ta(id int identity(1,1) ,x1 nvarchar(12),x2 nvarchar(12))
insert ta select
'aa' , 'a1'union all select
'aa', 'a2'union all select
'aa', 'a3'union all select
'bb', 'b1'union all select
'bb', 'b2'union all select
'bb', 'b3'union all select
'cc', 'c1'union all select
'cc', 'c2'union all select
'cc', 'c3'union all select
'dd', 'd1'union all select
'dd', 'd2'

if object_id('tb')is not null drop table tb
create table tb(x1 nvarchar(12),num int)
insert tb select
'aa',2 union all select
'bb',1 union all select
'cc',3


--1、
;with t as
(
select rn=row_number()over(partition by x1 order by newid()),*
from ta
)
select t.id,t.x1,t.x2
from t
join tb
on t.rn<=tb.num and t.x1=tb.x1
--2、
;with liang as
(
select a.x1,a.x2,b.num,
id=row_number() over(partition by a.x1 order by newid())
from ta as a join tb as b
on a.x1=b.x1
)
select x1,x2,id from liang
where id <=num;
--3、
select o.*
from tb cross apply (select top(tb.num) * from ta where ta.x1=tb.x1 order by newid()) o


chinaboyzyq 2009-08-04
  • 打赏
  • 举报
回复
好现在假定第一组我取2条,第二组我取3条,第三四我取3条,依次增加一条,看看怎么做。
lsd123 2009-08-04
  • 打赏
  • 举报
回复
.
weichaozu131083 2009-08-04
  • 打赏
  • 举报
回复
你干脆把VB代码贴出来,你说的不清不楚的,
weichaozu131083 2009-08-04
  • 打赏
  • 举报
回复
select top n from Table1 where x1 in(
select distinct x1 from table1
) order by newid
HiIan 2009-08-04
  • 打赏
  • 举报
回复
在下学习了!
chinaboyzyq 2009-08-04
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 js_szy 的回复:]
如果每组给个固定值的话,有好多组,aa,bb,cc,....

这个固定值你怎么给?存在另一个表里的?
[/Quote]

固定值在另一表里也行。
谢谢!!
加载更多回复(21)

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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