繁体   English   中英

sql中的union之间的where子句?

[英]Where clause between union all in sql?

我有一个查询,该查询通过使用Union条件垂直扩展数据。 以下是2个示例表:

create table #temp1(_row_ord int,CID int,_data varchar(10))

insert #temp1
values
(1,1001,'text1'),
(2,1001,'text2'),
(4,1002,'text1'),
(5,1002,'text2')


create table #temp2(_row_ord int,CID int,_data varchar(10))
insert #temp2
values
(1,1001,'sample1'),
(2,1001,'sample2'),
(4,1002,'sample1'),
(5,1002,'sample2')

--My query
select * from #temp1 
union
select * from #temp2 where CID in (select CID from #temp1)
order by _row_ord,CID

drop table #temp1,#temp2

所以我当前的输出是:

在此处输入图片说明

我想将无法在Union条件中使用“ where”子句的每个客户的详细信息归为一组。

我想要的输出:

在此处输入图片说明

有帮助吗? 订购者也无济于事。

我可以想象您想要一个CID所有行,它们按_row_ord从第一个表中的_row_ord排在第二个表中。 CID应该是最外面的排序标准。

如果是这样,则可以从表中选择文字。 让第一个表的文字小于第二个表的文字。 然后首先按CID排序,然后_row_ord义排序,最后按_row_ord

SELECT cid,
       _data
       FROM (SELECT 1 s,
                    _row_ord,
                    cid,
                    _data
                    FROM #temp1
             UNION ALL
             SELECT 2 s,
                    _row_ord,
                    cid,
                    _data
                    FROM #temp2) x
       ORDER BY cid,
                s,
                _row_ord;

分贝<>小提琴

如果我正确理解您的需求,则需要对输出进行排序,以使每个cid值的#temp1行出现在#temp2行之前。

您可以做的是为每个表生成附加的列ordnum分配值,仅用于排序目的,然后在外部select语句中将其删除。

select cid, _data
from (
  select 1 as ordnum, * 
  from #temp1 
  union all
  select 2 as ordnum, * 
  from #temp2 t2
  where exists (
    select 1
    from #temp1 t1
    where t1.cid = t2.cid
    )
  ) q
order by cid, ordnum

我还重写了您的where条件,该条件适用于使用exists运算符可以更快地运行的等效项。

现场演示-单击我!

产量

cid     _data
1001    text1
1001    text2
1001    sample1
1001    sample2
1002    text1
1002    text2
1002    sample1
1002    sample2

使用。 这是我第一次尝试使用您的sql

create table #temp1(_row_ord int,CID int,_data varchar(10))

insert #temp1
values
(1,1001,'text1'),
(2,1001,'text2'),
(4,1002,'text1'),
(5,1002,'text2')


create table #temp2(_row_ord int,CID int,_data varchar(10))
insert #temp2
values
(1,1001,'sample1'),
(2,1001,'sample2'),
(4,1002,'sample1'),
(5,1002,'sample2');

WITH result( _row_ord, CID,_data) AS
(
--My query
select * from #temp1 
union
select * from #temp2 where CID in (select CID from #temp1)


)
select * from tmp order by CID ,_data
drop table #temp1,#temp2

结果

_row_ord    CID _data
1   1001    sample1
2   1001    sample2
1   1001    text1
2   1001    text2
4   1002    sample1
5   1002    sample2
4   1002    text1
5   1002    text2

并集放置在两个结果集块之间,并形成一个结果集块。 如果要在特定块上使用where子句,可以将其放在:

select a from a where a = 1
union
select z from z


select a from a
union
select z from z where z = 1


select a from a where a = 1
union
select z from z where z = 1

并集中的第一个查询在输出中定义列名称。 您可以将输出包装在方括号中,对其进行别名处理,然后在整个批次中执行以下操作:

select * from
(
  select a as newname from a where a = 1
  union
  select z from z where z = 2
) o
where o.newname = 3

重要的是要注意,aa和zz将合并为新列o.newname。 结果,说出where o.newname将在来自a和z的所有行上进行过滤的位置(来自z的行也被堆叠到newname列中)。 外部查询只知道o.newname,不知道a或z

注意,上面的查询没有任何结果,因为我们知道联合仅将aa为1和zz为2的行输出为o.newname。 然后将此o.newname过滤为仅输出3的行,但没有3的行

select * from
(
  select a as newname from a
  union
  select z from z
) o
where o.newname = 3

该查询将选择a或z中aa为3或zz为3的任何行,这要归功于所过滤的并集

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM