使用SQL进行数据显示

时间:2011-02-11 07:34:02

标签: sql mysql tsql

我按顺序在SQL表中有一个数据:

Order Num Material ReqstDate   ReqstQty  ConfDate    ConfQty ShippedDate ShippedQty
===== === ======== ==========  ========  ==========  ======= =========== ==========
1001  1   ABC      01/10/2011  2500      01/12/2011  500     01/13/2011  500 
1001  1   ABC      99/99/9999  0         01/15/2011  2000    01/17/2011  1000
1001  1   ABC      99/99/9999  0         99/99/9999  0       01/19/2011  700
1001  1   ABC      99/99/9999  0         99/99/9999  0       01/21/2011  300
1001  2   EFG      02/15/2011  3750      02/20/2011  3500    02/21/2011  3000
1001  2   EFG      99/99/9999  0         99/99/9999  0       02/22/2011  500

我希望以这种方式显示上述数据:

Order Num Material ReqDate    ReqQty ConfDate    ConfQty ShippedDate ShippedQty
===== === ======== =======    ====== ==========  ======= =========== ==========
1001  1   ABC      01/10/2011 2500   01/12/2011  500     01/13/2011  500 
                                     01/15/2011  2000    01/17/2011  1000
                                                         01/19/2011  500
                                                         01/20/2011  500
      2   EFG      02/15/2011 3750   02/10/2011  3500    01/21/2011  3000
                                                         01/22/2001  500

4 个答案:

答案 0 :(得分:2)

SQL查询无法实现。

这似乎是一个可以使用报告工具解决的问题(例如BIRT for Eclipse)。 有了它,您可以根据需要对字段进行分组。

答案 1 :(得分:1)

SQL Server 您希望显示。这通常是在SQL中的某个地方完成的。但是如果在MSSMS中将输出设置为文本,则可以使用它来获得所需的输出。

declare @T table
(
  [Order] char(4), Num char(1), Material char (3), ReqstDate char(10), ReqstQty char(4),
  ConfDate char(10), ConfQty char(4), ShippedDate char(10), ShippedQty char(4)
)

insert into @T values
('1001', '1', 'ABC', '01/10/2011', '2500', '01/12/2011', '500 ', '01/13/2011', '500 '), 
('1001', '1', 'ABC', '99/99/9999', '0   ', '01/15/2011', '2000', '01/17/2011', '1000'),
('1001', '1', 'ABC', '99/99/9999', '0   ', '99/99/9999', '0   ', '01/19/2011', '700 '),
('1001', '1', 'ABC', '99/99/9999', '0   ', '99/99/9999', '0   ', '01/21/2011', '300 '),
('1001', '2', 'EFG', '02/15/2011', '3750', '02/20/2011', '3500', '02/21/2011', '3000'),
('1001', '2', 'EFG', '99/99/9999', '0   ', '99/99/9999', '0   ', '02/22/2011', '500 ')

;with cte as
(
  select
    [Order],
    Num,
    Material,
    ReqstDate,
    ReqstQty,
    ConfDate,
    ConfQty,
    ShippedDate,
    ShippedQty,
    row_number() over(order by cast(ShippedDate as datetime)) as n
  from @T
)
select
  isnull(nullif(C1.[Order], C2.[Order]), '') as [Order],
  isnull(nullif(C1.Num, C2.Num), '') as Num,
  isnull(nullif(C1.Material, C2.Material), '') as Material,
  isnull(nullif(C1.ReqstDate, '99/99/9999'), '') as ReqstDate,
  isnull(nullif(C1.ReqstQty, '0   '), '') as ReqstQty,
  isnull(nullif(C1.ConfDate, '99/99/9999'), '') as ConfDate,
  isnull(nullif(C1.ConfQty, '0   '), '') as ConfQty,
  isnull(nullif(C1.ShippedDate, '99/99/9999'), '') as ShippedDate,
  isnull(nullif(C1.ShippedQty, '0   '), '') as ShippedQty
from cte as C1
  left outer join cte as C2
    on C1.n = C2.n+1
order by C1.n

答案 2 :(得分:0)

如果您正在使用tsql(即microsoft sql server。您还使用支持ROW_NUMBER的Sql服务器(即Sql Server 2005或更高版本)使用MySql标记您的问题,这是另一个品牌的数据库)。

我假设ReqstDate,ConfDate和ShippedDate是nvarchars(否则在这些字段中不可能有值'99 / 99/9999')。您应该将这些列转换为datetime字段,否则当您获得类似于01/15/2012的值时,查询中的所有ORDER BY子句都会出错(查询适用于您提供的数据集,但仅因为日期时间值都在其他及时使字母顺序等于时间顺序)。当然,如果你打算这样做,你将需要使用NULL代替'99 / 99/9999'并且在查询中将'!= '99 / 99/9999''改为'为'空'。

但是,我建议使用报告工具或简单的选择和一些代码来生成所需的表。查询相当复杂且难以维护。作为一般规则,数据库为调用者提供数据,而所有格式化应由调用者自己完成。

修改:Mikael Eriksson's answer更好&比我的简单。我对日期时间字段的评论仍然存在。

select case when ROW_NUMBER() over (partition by [Order] Order by [order]) = 1
             and [order] != 0
       then cast([Order] as nvarchar)
       else ''
   end as [order],
   case when ROW_NUMBER() over (partition by [order], num 
                                Order by [order], num) = 1
             and num != 0
       then cast(num as nvarchar)
       else ''
   end as num,
   case when ROW_NUMBER() over (partition by [order], num, Material 
                                Order by [order], num, Material) = 1
       then Material
       else ''
   end as Material,
   case when ROW_NUMBER() over (partition by [order], num, Material, ReqstDate 
                                Order by [order], num, Material, ReqstDate) = 1
             and ReqstDate != '99/99/9999'
       then ReqstDate
       else ''
   end as ReqstDate,       
   case when ROW_NUMBER() over (partition by [order], num, Material, ReqstDate, ReqstQty 
                                Order by [order], num, Material, ReqstDate, ReqstQty) = 1
             and ReqstQty != 0
       then cast(ReqstQty as nvarchar)
       else ''
   end as ReqstQty, 
   case when ROW_NUMBER() over (partition by [order], num, Material, ReqstDate, ReqstQty, ConfDate 
                                Order by [order], num, Material, ReqstDate, ReqstQty, ConfDate) = 1
             and ConfDate != '99/99/9999'
       then ConfDate
       else ''
   end as ConfDate,    
   case when ROW_NUMBER() over (partition by [order], num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty 
                                Order by [order], num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty) = 1
             and ConfQty != 0
       then cast(ConfQty as nvarchar)
       else ''
   end as ConfQty,     
   case when ROW_NUMBER() over (partition by ShippedDate, num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty, ShippedDate 
                                Order by ShippedDate, num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty, ShippedDate) = 1
             and ShippedDate != '99/99/9999'
       then ShippedDate
       else ''
   end as ShippedDate,     
   case when ROW_NUMBER() over (partition by [order], num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty, ShippedDate, ShippedQty 
                                Order by [order], num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty, ShippedDate, ShippedQty) = 1
             and ShippedQty != 0
       then cast(ShippedQty as nvarchar)
       else ''
   end as ShippedQty
   from yourTable
   order by ROW_NUMBER() over (order by [order], num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty, ShippedDate, ShippedQty)

答案 3 :(得分:0)

SQL Server 2005 +。

;
WITH
  data ([Order], Num, Material, ReqstDate, ReqstQty, ConfDate, ConfQty,
    ShippedDate, ShippedQty)
  AS (
    SELECT 1001, 1, 'ABC', '01/10/2011', 2500, '01/12/2011',  500, '01/13/2011',  500  UNION ALL
    SELECT 1001, 1, 'ABC', '99/99/9999',    0, '01/15/2011', 2000, '01/17/2011', 1000  UNION ALL
    SELECT 1001, 1, 'ABC', '99/99/9999',    0, '99/99/9999',    0, '01/19/2011',  700  UNION ALL
    SELECT 1001, 1, 'ABC', '99/99/9999',    0, '99/99/9999',    0, '01/21/2011',  300  UNION ALL
    SELECT 1001, 2, 'EFG', '02/15/2011', 3750, '02/20/2011', 3500, '02/21/2011', 3000  UNION ALL
    SELECT 1001, 2, 'EFG', '99/99/9999',    0, '99/99/9999',    0, '02/22/2011',  500
  ),
  numbereddata AS (
    SELECT
      [Order], Num, Material, ReqstDate, ReqstQty,
      ConfDate, ConfQty, ShippedDate, ShippedQty,
      rownum1 = ROW_NUMBER() OVER (PARTITION BY [Order] ORDER BY Num, CONVERT(datetime, ShippedDate)),
      rownum2 = ROW_NUMBER() OVER (PARTITION BY [Order], Num ORDER BY CONVERT(datetime, ShippedDate))
    FROM data
  )
SELECT
  [Order]  = CASE rownum1 WHEN 1 THEN CAST([Order] AS varchar) ELSE '' END,
  Num      = CASE rownum2 WHEN 1 THEN CAST(Num AS varchar) ELSE '' END,
  Material = CASE rownum2 WHEN 1 THEN CAST(Num AS varchar) ELSE '' END,

  ReqstDate = CASE ReqstDate WHEN '99/99/9999' THEN '' ELSE ReqstDate END,
  ReqstQty  = CASE ReqstDate WHEN '99/99/9999' THEN '' ELSE CAST(ReqstQty AS varchar)  END,

  ConfDate = CASE ConfDate WHEN '99/99/9999' THEN '' ELSE ConfDate END,
  ConfQty  = CASE ConfDate WHEN '99/99/9999' THEN '' ELSE CAST(ConfQty AS varchar)  END,

  ShippedDate = CASE ShippedDate WHEN '99/99/9999' THEN '' ELSE ShippedDate END,
  ShippedQty  = CASE ShippedDate WHEN '99/99/9999' THEN '' ELSE CAST(ShippedQty AS varchar)  END
FROM numbereddata nd
ORDER BY nd.[Order], nd.Num, CONVERT(datetime, nd.ShippedDate)