简体   繁体   English

在SQL中从一行中选择多行

[英]Selecting multiple row from one row in SQL

I have the following output with me from multiple tables 我从多个表中得到以下输出

id    b   c   b     e    b     g  
abc  2   123  3   321   7   876  
abd  2   456  3   452   7   234  
abe  2   0    3   123   7   121  
abf  2   NULL 3   535   7   1212  

Now I want to insert these values into another table and the insert query for a single command is as follows: 现在我想将这些值插入另一个表中,单个命令的insert查询如下:

insert into resulttable values (id,b,c), (id,b,e) etc.

For that I need to do a select such that it gives me 为此,我需要做一个选择,它给了我

id,b,c
id,b,e etc

I dont mind getting rid of b too as it can be selected using c# query. 我也不介意摆脱b,因为它可以使用c#查询进行选择。

How can I achieve the same using a single query in sql. 如何在sql中使用单个查询实现相同的功能。 Again please note its not a table its an output from different tables 请再次注意,它不是一个表,它是来自不同表的输出

My query should look as follows: from the above I need to do something like 我的查询应如下所示:从上面我需要做类似的事情

select b.a, b.c
union all
select b.d,b.e from  (select a,c,d,e from <set of join>)  b

But unfortunately that does not work 但不幸的是,这不起作用

INSERT resulttable
SELECT id, b, c
FROM original
UNION
SELECT id, b, e
FROM original

Your example has several columns named 'b' which isn't allowed... 您的示例有几个名为'b'的列,不允许使用...

Here, #tmporigin refers to your original query that produces the data in the question. 这里, #tmporigin是指您在问题中生成数据的原始查询。 Just replace the table name with a subquery. 只需用子查询替换表名即可。

insert into resulttable
select
 o.id,
 case a.n when 1 then b1 when 2 then b2 else b3 end,
 case a.n when 1 then c when 2 then e else g end
from #tmporigin o
cross join (select 1n union all select 2 union all select 3) a


The original answer below, using CTE and union all requiring CTE evaluation 3 times 下面的原始答案,使用CTE和union都要求CTE评估3次

I have the following output with me from multiple tables 我从多个表中得到以下输出

So set that query up as a Common Table Expression 因此,将该查询设置为公用表表达式

;WITH CTE AS (
   -- the query that produces that output
)
select id,b1,c from CTE
union all
select id,b2,e from CTE
union all
select id,b3,g from CTE

NOTE - Contrary to popular belief, your CTE while conveniently written once, is run thrice in the above query, once for each of the union all parts. 注意 - 与流行的看法相反,你的CTE虽然方便地写了一次,但在上面的查询中运行三次 ,每次联合所有部分都会运行一次。

NOTE ALSO that if you actually name 3 columns "b" (literally), there is no way to identify which b you are referring to in anything that tries to reference the results - in fact SQL Server will not let you use the query in a CTE or subquery. 注意 ,如果您实际上将3列命名为“b”(字面意思),则无法确定在尝试引用结果的任何内容中引用哪个b - 实际上SQL Server将不允许您在CTE或子查询。

The following example shows how to perform the above, as well as (if you show the execution plan) revealing that the CTE is run 3 times! 以下示例显示了如何执行上述操作,以及(如果您显示执行计划)显示CTE运行3次! (the lines between --- BELOW HERE and --- ABOVE HERE is a mock of the original query that produces the output in the question. --- BELOW HERE--- ABOVE HERE之间的界限是original query的模拟,它在问题中产生输出。

if object_id('tempdb..#eav') is not null drop table #eav
;
create table #eav (id char(3), b int, v int)
insert #eav select 'abc', 2, 123
insert #eav select 'abc', 3, 321
insert #eav select 'abc', 7, 876
insert #eav select 'abd', 2, 456
insert #eav select 'abd', 3, 452
insert #eav select 'abd', 7, 234
insert #eav select 'abe', 2, 0
insert #eav select 'abe', 3, 123
insert #eav select 'abe', 7, 121
insert #eav select 'abf', 3, 535
insert #eav select 'abf', 7, 1212

;with cte as (
---- BELOW HERE
    select id.id, b1, b1.v c, b2, b2.v e, b3, b3.v g
    from
    (select distinct id, 2 as b1, 3 as b2, 7 as b3 from #eav) id
    left join #eav b1 on b1.b=id.b1 and b1.id=id.id
    left join #eav b2 on b2.b=id.b2 and b2.id=id.id
    left join #eav b3 on b3.b=id.b3 and b3.id=id.id
---- ABOVE HERE
)
select b1, c from cte
union all
select b2, e from cte
union all
select b3, g from cte
order by b1

You would be better off storing the data into a temp table before doing the union all select. 在进行union all选择之前,最好将数据存储到临时表中。

Instead of this which does not work as you know 而不是像你所知的那样不起作用

select b.a, b.c
union all
select b.d,b.e from  (select a,c,d,e from <set of join>)  b

You can do this. 你可以这样做。 Union with repeated sub-select 联盟反复分选

select b.a, b.c from (select a,c,d,e from <set of join>)  b
union all
select b.d, b.e from (select a,c,d,e from <set of join>)  b

Or this. 或这个。 Repeated use of cte. 反复使用cte。

with cte as
(select a,c,d,e from <set of join>)
select b.a, b.c from cte b
union all
select b.d, b.e from cte b

Or use a temporary table variable. 或者使用临时表变量。

declare @T table (a int, c int, d int, e int)
insert into @T values
select a,c,d,e from <set of join>

select b.a, b.c from @T  b
union all
select b.d, b.e from @T  b

This code is not tested so there might be any number of typos in there. 此代码未经过测试,因此可能存在任何数量的拼写错误。

I'm not sure if I understood Your problem correctly, but i have been using something like this for some time: 我不确定我是否正确理解你的问题,但我已经使用了这样的东西一段时间了:

let's say we have a table 假设我们有一张桌子

ID Val1 Val2
1 AB
2 CD

to obtain a reslut like 获得像这样的结果

ID Val
1 A
1 B
2 C
2 D

You can use a query : 您可以使用查询:

select ID, case when i=1 then Val1 when i=2 then Val2 end as Val
from table
left join ( select 1 as i union all select 2 as i ) table_i on i=i

which will simply join the table with a subquery containing two values and create a cartesian product. 它将简单地将表与包含两个值的子查询连接起来,并创建一个笛卡尔积。 In effect, all rows will be doubled (or multiplied by how many values the subquery will have). 实际上,所有行都将加倍(或乘以子查询将具有的值)。 You can vary the number of values depending on how many varsions of row You'll need. 您可以根据您需要的行数来改变值的数量。 Depending on the value of i, Val will be Val1 or Val2 from original table. 根据i的值,Val将是原始表中的Val1或Val2。 If you'll see the execution plan, there will be a warning that the join has no join predicates (because of i=i), but it is ok - we want it. 如果您将看到执行计划,则会出现一个警告:连接没有连接谓词(因为i = i),但是没关系 - 我们想要它。 This makes queries a bit large (in terms of text) because of all the case when, but are quite easy to read if formatted right. 这使得查询有点大(在文本方面),因为所有情况都是,但如果格式正确则很容易阅读。 I needed it for stupid tables like "BigID, smallID1, smallID2...smallID11" that was spread across many columns I don't know why. 我需要它用于愚蠢的表,如“BigID,smallID1,smallID2 ... smallID11”,它分布在许多列,我不知道为什么。 Hope it helps. 希望能帮助到你。 Oh, I use a static table with 10000 numbers, so i just use 哦,我使用10000个数字的静态表,所以我只是使用

join tab10k on i<=10

for 10x row. 10倍排。 I apologize for stupid formatting, I'm new here. 我为愚蠢的格式道歉,我是新来的。

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

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