Data Display using SQL
I have a data in SQL table in this order:
Order Num Material ReqstDate ReqstQty ConfDate ConfQty ShippedDate ShippedQty
===== === ======== ========== ===开发者_JS百科===== ========== ======= =========== ==========
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
I want the above data to be displayed in this manner:
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
It is not possible with a SQL query.
It seems an issue that can be solved with a reporting tool (for example BIRT for Eclipse). With it you can group the fields as you want.
SQL Server You want this to be displayed. That is usually done somewhere not in SQL. But if you set output to text in MSSMS you can use this to get the desired output.
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
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)
This is possible if you are using tsql (i.e. microsoft sql server. You also tagged your question with MySql which is another brand of database) with a sql server that supports ROW_NUMBER (i.e. Sql Server 2005 or later).
I'm assuming that ReqstDate, ConfDate and ShippedDate are nvarchars (otherwise it would be impossible to have the value '99/99/9999' in those fields). You should convert those columns into datetime fields otherwise all the ORDER BY clauses in the query will go wrong when you get a value like 01/15/2012 (The query works for the dataset you gave but only because the datetime values are all near each other in time so that the alphabetical order is equal to the chronological order). Off course, if you you are going to do this, you will need to use NULL for '99/99/9999' and in the query change '!= '99/99/9999'' to 'is null'.
However, I would advise to use a reporting tool or a simple select and some code to generate the table you want. The query is rather complex and difficult to maintain. As a general rule, a database provides the caller with data while all the formatting should be done by the caller itself.
Edit : Mikael Eriksson's answer is better & simpler than mine. My remark about the datetime fields still stands however.
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)
精彩评论