【问题标题】:Union columns and remove blanks联合列和删除空白
【发布时间】:2015-03-23 14:16:46
【问题描述】:

我有一个看起来像这样的表格(出于示例目的,我已将其缩短)

no               no19             no68
3387034694344500        
3387452540705400        
3388486878919450                
                 3371522572594880   
                 3372232397709690   
                 3373608476884750   
                                  3382142940562320
                                  3382142940562320
                                  3383084144363070

所以不,no19 和 no68 是 3 个不同的列,但是 'no19' 列中的数据在 'no' 列中的数据结束后的下一行开始。

在这些列之间我有更多的数据,我想创建一个可读的表。我已使用以下代码将这些列合并为一个:

 CREATE TABLE MULTICURRENCY_CHECK
(
TOKEN varchar(255)
)                           
INSERT INTO MULTICURRENCY_CHECK
(
TOKEN
)
SELECT no FROM book1
    UNION ALL
SELECT no19 FROM book1
    UNION ALL
SELECT no68 FROM book1

问题是,我得到的结果是这样的:

TOKEN
3387034694344500        
3387452540705400        
3388486878919450


3371522572594880
3372232397709690    
3373608476884750


3382142940562320
3382142940562320
3383084144363070

所以在 TOKEN 列之间有空白行。我试图删除它们,但它通过简单的删除命令但它不起作用(尝试了下面的这两个):

delete from multicurrency_check where TOKEN = ' '
delete from multicurrency_check where TOKEN is NULL

也许我应该以不同的方式处理这张桌子,也许更快?因为原始表看起来像这些(只是示例数据)

no                   a      b      no19             c    d      no68
    3387034694344500 data1  data4   
    3387452540705400 data2  data5   
    3388486878919450 data3  data6           
                                  3371522572594880 data7 data10
                                  3372232397709690 data8 data11
                                  3373608476884750 data9 data12
                                                                3382142940562320
                                                                3382142940562320
                                                                3383084144363070

所以我最后想要的是这样的表格:

 | TOKEN | a | b | c | d

其中 token 是 no、no19 和 no68 的合并,然后是 a、b、c、d 列,其数据与来自 TOKEN 列的适当 id 匹配(a、b、c、d 可以为 null)

【问题讨论】:

  • 我不明白问题的第二部分。但是,您可以通过以下查询删除“空”记录:DELETE FROM multicurrency_check where COALESCE(RTRIM(LTRIM(TOKEN)),'') = '';
  • 对于给定的数据,你能用预期的转换填充结果表吗?
  • 好的,它正在与 COALESCE 合作(不太了解 transact-sql)。我想我会处理剩下的,现在只是加入表格的问题。

标签: sql sql-server syntax


【解决方案1】:

您可以在 UNION 查询中删除它们,例如:

SELECT no FROM table WHERE no IS NOT NULL
UNION
SELECT no19 FROM table WHERE no19 IS NOT NULL
UNION 
SELECT no68 FROM table where no68 IS NOT NULL

您也可以使用 COALESCE() 代替 union,因为一列仅在另一列为空时包含数据:

SELECT COALESCE(no, no19, no68) FROM table

您可以从上面的查询开始并在它们的基础上构建,而不是将这些值放在它们自己的表中。假设您还想在结果中引入 A、B 或 C、D:

SELECT COALESCE(no, no19, no68) as newno, COALESCE(a,c) as ac, COALESCE(b,d) as bd FROM table;

至于为什么您的 DELETE 不起作用,也许那些 NULL 不是 NULL。也许他们持有一个 TAB 字符或 50 个空格?在这种情况下,@sidux 对您的 Q 的评论会起到作用。修剪字段并查看其值为='' 的位置。

【讨论】:

  • 有趣的事情,我用这个代码:SELECT COALESCE(no, no19, no68, no93, no107) as 'Token', COALESCE(localdate, LocalDate13, LocalDate62, LocalDate87, LocalDate101) as 'Date' FROM Book1 但它没有向我显示所有结果,因为一些令牌编号混乱并且有文本字符串,所以更好的使用是@marcin wojdak SELECT isnull(no,'')+isnull(no19,'' 建议的这段代码)+isnull(no68,'')+isnull(no93,'')+isnull(no107,'') as 'Token', isnull(localdate,'')+isnull(LocalDate13,'')+isnull(LocalDate62, '')+isnull(LocalDate87,'')+isnull(LocalDate101,'') as 'Date', FROM book1
  • 这很有趣。我怀疑正在发生的事情是 '+' 运算符正在强制使用 CAST(field AS NumberFormat) 以便它可以做到这一点。因此,“+”虽然从 CPU 的角度来看可能更慢,但同时完成了 CASTCOALESCE 的工作。如果您的数据不大,那么这是一个可靠的解决方案。
  • 目前规模不大,因为我只处理示例,但目的是将其应用于非常大的数据库。那你有什么建议呢?
  • 我认为您将遇到的最大性能问题源于表中的脏数据。似乎您的记录看起来为 NULL,但实际上其中包含空格(制表符和空格)。这会使COALESCE() 变得无用,因此您必须依赖更简单的解决方案,例如isnull()+isnull()...COALESCE(TRIM(field), TRIM(field2),...),当您的数据增长时,这两种解决方案都会变得昂贵。如果性能会成为问题,请清理数据。
  • 清除数据不是一种选择,因为它是从外部发送并加载到数据库中的。实际上,我需要的只是每天、每周和每月的作品。您认为如果我先在适当的时间段内创建视图然后运行查询会更快吗?
【解决方案2】:

可能是这样的:

select
isnull(no,'')+isnull(no19,'')+isnull(no68,''),
a,b,c,d
from book1

这应该将所有标记连接成一行(并且只有 no、no19 和 no68 中的一个具有值)。

【讨论】:

  • 酷,这比 UNION ALL 快得多
【解决方案3】:

我创建了一个包含 3 个文本列的表 'foo',如下所示:

       column1            column2            column3
       -------            -------            -------
row1   3371522572594880                      3373608476884750
row2   asdfasdf                              asdfasdf
row3                      3387452540705400   3388486878919450

然后执行查询

select token from(
select column1 as token from foo where column1 != '' 
union all 
select column2 as token from foo where column2 != ''
union all
select column3 as token from foo where column3 != ''
)

得到了结果:

token
3371522572594880
asdfasdf
3387452540705400
3388486878919450
3373608476884750
asdfasdf

这就是你所追求的吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 2013-08-15
    相关资源
    最近更新 更多