2010-04-28 96 views
1

如何在這種情況下編寫Sql或LinqToSql?如何爲這種情況編寫Sql或LinqToSql?

表有下列數據:

Id UserName Price  Date  Status 

1 Mike 2 2010-4-25 0:00:00 Success 
2 Mike 3 2010-4-25 0:00:00 Fail 
3 Mike 2 2010-4-25 0:00:00 Success 
4 Lily 5 2010-4-25 0:00:00 Success 
5 Mike 1 2010-4-25 0:00:00 Fail 
6 Lily 5 2010-4-25 0:00:00 Success 
7 Mike 2 2010-4-26 0:00:00 Success 
8 Lily 5 2010-4-26 0:00:00 Fail 
9 Lily 2 2010-4-26 0:00:00 Success 
10 Lily 1 2010-4-26 0:00:00 Fail 

我想從數據彙總結果,該結果應該是:

UserName Date TotalPrice TotalRecord SuccessRecord FailRecord 
Mike  2010-04-25 8   4   2   2 
Lily  2010-04-25 10   2   2   0 
Mike  2010-04-26 2   1   1   0 
Lily  2010-04-26 8   3   1   2 

The TotalPrice is the sum(Price) groupby UserName and Date 
The TotalRecord is the count(*) groupby UserName and Date 
The SuccessRecord is the count(*) groupby UserName and Date where Status='Success' 
The FailRecord is the count(*) groupby UserName and Date where Status='Fail' 
The TotalRecord = SuccessRecord + FailRecord 

在SQL Server 2005數據庫的腳本是:

/****** Object: Table [dbo].[Pay] Script Date: 04/28/2010 22:23:42 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Pay]') AND type in (N'U')) 
BEGIN 
CREATE TABLE [dbo].[Pay](
[Id] [int] IDENTITY(1,1) NOT NULL, 
[UserName] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 
[Price] [int] NULL, 
[Date] [datetime] NULL, 
[Status] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL, 
CONSTRAINT [PK_Pay] PRIMARY KEY CLUSTERED 
(
[Id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) 
) 
END 
GO 
SET IDENTITY_INSERT [dbo].[Pay] ON 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (1, N'Mike', 2, CAST(0x00009D6300000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (2, N'Mike', 3, CAST(0x00009D6300000000 AS DateTime), N'Fail') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (3, N'Mike', 2, CAST(0x00009D6300000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (4, N'Lily', 5, CAST(0x00009D6300000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (5, N'Mike', 1, CAST(0x00009D6300000000 AS DateTime), N'Fail') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (6, N'Lily', 5, CAST(0x00009D6300000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (7, N'Mike', 2, CAST(0x00009D6400000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (8, N'Lily', 5, CAST(0x00009D6400000000 AS DateTime), N'Fail') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (9, N'Lily', 2, CAST(0x00009D6400000000 AS DateTime), N'Success') 
INSERT [dbo].[Pay] ([Id], [UserName], [Price], [Date], [Status]) VALUES (10, N'Lily', 1, CAST(0x00009D6400000000 AS DateTime), N'Fail') 
SET IDENTITY_INSERT [dbo].[Pay] OFF 

回答

1

一個可能的SQL查詢將是:

SELECT 
    UserName 
    ,Date 
    ,sum(Price) TotalPay 
    ,count(*) TotalRecord 
    ,sum(case Status when 'Success' then 1 else 0 end) SuccessRecord 
    ,sum(case Status when 'Success' then 0 else 1 end) FailRecord 
from Pay 
group by 
    UserName 
    ,Date 
order by 
    Date 
    ,UserName desc 

這假設當Status爲NULL時,您會將1添加到FailRecord。

+0

謝謝。但是你能提供一個LinqToSql版本的代碼嗎? – Mike108 2010-04-28 14:51:37

+0

對不起,我從未使用過Linq。轉換不應該那麼棘手......? – 2010-04-28 15:19:09

+0

感謝您的SQL,並且我找到了一個工具(Linqer)來完成轉換工作。 – Mike108 2010-04-28 15:26:34

1

覺得這樣做的伎倆

修訂

var summary = from record in table 
       group record by record.UserName + record.Date.ToString() into grp 
       select new 
       { 
        grp.First().UserName, 
        grp.First().Date, 
        TotalPrice = grp.Sum(record => record.Price), 
        TotalRecord = grp.Count(), 
        SuccessRecord = grp.Count(record => record.Status == "Success"), 
        FailRecord = grp.Count(record => record.Status == "Fail") 
       }; 
+0

你的代碼只有兩個結果: Mike 2010-4-25 0:00:00 10 5 3 2 Lily 2010-4-25 0:00:00 18 5 3 2 – Mike108 2010-04-28 15:25:27

+0

對不起,只檢查一下編譯。我修復了我的答案。無法讓它與2組一起工作,所以我改變了組條件。現在結果是OK。 – Fede 2010-04-28 16:01:32

+0

非常感謝。 – Mike108 2010-04-28 16:39:50