【问题标题】:Single query to split out data of one column, into two columns, from the same table based on different criteria [SQL]单个查询根据不同的条件从同一个表中将一列的数据拆分为两列 [SQL]
【发布时间】:2020-09-30 23:15:15
【问题描述】:

我在表中有以下数据,这是从具有多列的表中显示的单列,但只有来自该列的数据需要使用查询拉入两列输出:

+----------------+--+
| 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 示例以使此类查询正常工作。

【问题讨论】:

    标签: sql sql-server string tsql pivot


    【解决方案1】:

    这很丑陋,但可行。首先,您需要一个定义行顺序的列 - 我假设您有这样一个列,称为 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
    

    Demo on DB Fiddle

    短数据 |长数据 :------------ | :------------ 1 DEC20 DDD | 1 七月 20 日 DDD80 2021 年 1 月 1 日 DDD | 1 JUL20DDDD40 2020 年 7 月 1 日 DDD | 1 JUL20DDDD80 | 2020 年 6 月 1 日 DDD50 | 1 JUN20DDDD50

    【讨论】:

    • 忙碌...该解决方案远超我的技能。非常感谢。仅供参考,我认为数据集可能是其存储方式的问题......?但这不在我的掌控之中。再次感谢
    猜你喜欢
    • 1970-01-01
    • 2015-11-16
    • 2023-01-10
    • 2022-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多