我在表中有以下数据,这是从表中显示的具有多列的单列,但是仅需要使用查询将该列中的数据提取到两列输出中:
+----------------+--+
| DataText | |
| 1 DEC20 DDD | |
| 1 JUL20 DDD | |
| 1 JAN21 DDD | |
| 1 JUN20 DDD500 | |
| 1 JUN20 DDD500 | |
| 1 JUN20DDDD500 | |
| 1 JUN20DDDD500 | |
| 1 JUL20 DDD800 | |
| 1 JUL20 DDD800 | |
| 1 JUL20DDDD800 | |
| 1 JUL20DDDD400 | |
| 1 JUL20DDDD400 | |
+----------------+--+
所需结果:基于数据的前13个字符的不同值,基于“长数据”和“短数据”分为两列,但两列的输出仅给出前13个字符:>
+-------------+-------------+
| ShortData | LongData |
| 1 DEC20 DDD | 1 JUN20 DDD |
| 1 JUL20 DDD | 1 JUN20DDDD |
| 1 JAN21 DDD | 1 JUL20 DDD |
| | 1 JUL20DDDD |
+-------------+-------------+
类似的东西:
Select
(Select DISTINCT LEFT(DataText,13)
From myTable)
Where LEN(DataText)=13) As ShortData
,
(Select DISTINCT LEFT(DataText,13)
From myTable)
Where LEN(DataText)>13) As LongData
如果可能的话,我也只想查询/“扫描”该表一次。我无法修改任何SO示例来使这种查询正常工作。
答案 0 :(得分:2)
这很丑陋,但可行。首先,您需要一个定义行顺序的列-我假设您有这样的列,称为id
。
然后,您可以选择不同的文本,根据它们的长度将它们放在不同的组中,最后旋转:
select
max(case when grp = 0 then dataText end) shortData,
max(case when grp = 1 then dataText end) longData
from (
select
dataText,
grp,
row_number() over(partition by grp order by id) rn
from (
select
id,
case when len(dataText) <= 13 then 0 else 1 end grp,
substring(dataText, 1, 13) dataText
from (select min(id) id, dataText from mytable group by dataText) t
) t
) t
group by rn
如果您对按字符串列本身对记录进行排序感到满意,那么它会更简单(对于示例数据,它会产生相同的结果):
select
max(case when grp = 0 then dataText end) shortData,
max(case when grp = 1 then dataText end) longData
from (
select
dataText,
grp,
row_number() over(partition by grp order by dataText) rn
from (
select distinct
case when len(dataText) <= 13 then 0 else 1 end grp,
substring(dataText, 1, 13) dataText
from mytable
) t
) t
group by rn
shortData | longData :---------- | :------------ 1 DEC20 DDD | 1 JUL20 DDD80 1 JAN21 DDD | 1 JUL20DDDD40 1 JUL20 DDD | 1 JUL20DDDD80 null | 1 JUN20 DDD50 null | 1 JUN20DDDD50