XSLT存档  

不及格的程序员-八神

 查看分类:  ASP.NET XML/XSLT JavaScripT   我的MSN空间Blog

我们知道在SQL中一共有五种JOIN操作:INNER JOIN、LEFT OUTER JOIN、RIGHT OUTER JOIN、FULL OUTER JOIN、CROSS JOIN

1>先创建两个表Group、User,两表的关系是N:N

复制代码
CREATE TABLE [dbo].[Group](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [GroupName] [nvarchar](50) NULL,
     CONSTRAINT [PK_Group] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]

CREATE TABLE [dbo].[User](
        [Id] [int] IDENTITY(1,1) NOT NULL,
        [UserName] [nvarchar](50) NULL,
        [GroupId] [int] NULL,
     CONSTRAINT [PK_User] PRIMARY KEY CLUSTERED
    (
        [Id] ASC
    )WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
复制代码

2>测试数据

        

复制代码
INSERT [dbo].[User] ([Id], [UserName], [GroupId]) VALUES (1, N'张1', 1)
INSERT [dbo].[User] ([Id], [UserName], [GroupId]) VALUES (2, N'张2', 2)
INSERT [dbo].[User] ([Id], [UserName], [GroupId]) VALUES (3, N'张3', 4)

INSERT [dbo].[Group] ([Id], [GroupName]) VALUES (1, N'A')
INSERT [dbo].[Group] ([Id], [GroupName]) VALUES (2, N'B')
INSERT [dbo].[Group] ([Id], [GroupName]) VALUES (3, N'C')
复制代码

3>连接大全

复制代码
Sql:
SELECT [t0].[GroupName], [t1].[UserName]
FROM [Group] AS [t0]
INNER JOIN [User] AS [t1] ON ([t0].[Id]) = [t1].[GroupId]

Linq to Sql:
from g in Groups
join u in Users
on g.Id  equals u.GroupId
select new { GroupName=g.GroupName, UserName=u.UserName}

Lambda:
Groups.Join 
(
      Users, 
      g => (Int32?)(g.Id), 
      u => u.GroupId, 
      (g, u) => 
         new  
         {
            GroupName = g.GroupName, 
            UserName = u.UserName
         }
   )
复制代码


 

复制代码
Sql:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = ''
-- EndRegion
SELECT [t0].[GroupName], 
    (CASE 
        WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(50),@p0)
        ELSE [t2].[UserName]
     END) AS [UserName]
FROM [Group] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[UserName], [t1].[GroupId]
    FROM [User] AS [t1]
    ) AS [t2] ON ([t0].[Id]) = [t2].[GroupId]

Linq to Sql:
from g in Groups
join u in Users
on g.Id  equals u.GroupId
into Grp
from grp in Grp.DefaultIfEmpty()
select new { GroupName=g.GroupName, UserName=(grp==null)?"":grp.UserName}

Lambda:
Groups.GroupJoin (
      Users, 
      g => (Int32?)(g.Id), 
      u => u.GroupId, 
      (g, Grp) => 
         new  
         {
            g = g, 
            Grp = Grp
         }
   ) .SelectMany (
      temp0 => temp0.Grp.DefaultIfEmpty (), 
      (temp0, grp) => 
         new  
         {
            GroupName = temp0.g.GroupName, 
            UserName = (grp == null) ? "" : grp.UserName
         }
   )
复制代码


 

复制代码
Sql:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = ''
-- EndRegion
SELECT 
    (CASE 
        WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(50),@p0)
        ELSE [t2].[GroupName]
     END) AS [GroupName], [t0].[UserName]
FROM [User] AS [t0]
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[Id], [t1].[GroupName]
    FROM [Group] AS [t1]
    ) AS [t2] ON [t0].[GroupId] = ([t2].[Id])

Linq to Sql:
from u in Users
join g in Groups
on u.GroupId equals g.Id
into Grp
from grp in Grp.DefaultIfEmpty()
select new { GroupName=(grp==null)?"":grp.GroupName, UserName=u.UserName}

Lambda:
Users.GroupJoin (
      Groups, 
      u => u.GroupId, 
      g => (Int32?)(g.Id), 
      (u, Grp) => 
         new  
         {
            u = u, 
            Grp = Grp
         }
   ).SelectMany (
      temp0 => temp0.Grp.DefaultIfEmpty (), 
      (temp0, grp) => 
         new  
         {
            GroupName = (grp == null) ? "" : grp.GroupName, 
            UserName = temp0.u.UserName
         }
   )

   
复制代码


 

复制代码
Sql:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = ''
DECLARE @p1 NVarChar(1000) = ''
-- EndRegion
SELECT DISTINCT [t7].[GroupName], [t7].[value] AS [UserName]
FROM (
    SELECT [t6].[GroupName], [t6].[value]
    FROM (
        SELECT [t0].[GroupName], 
            (CASE 
                WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(50),@p0)
                ELSE [t2].[UserName]
             END) AS [value]
        FROM [Group] AS [t0]
        LEFT OUTER JOIN (
            SELECT 1 AS [test], [t1].[UserName], [t1].[GroupId]
            FROM [User] AS [t1]
            ) AS [t2] ON ([t0].[Id]) = [t2].[GroupId]
        UNION ALL
        SELECT 
            (CASE 
                WHEN [t5].[test] IS NULL THEN CONVERT(NVarChar(50),@p1)
                ELSE [t5].[GroupName]
             END) AS [value], [t3].[UserName]
        FROM [User] AS [t3]
        LEFT OUTER JOIN (
            SELECT 1 AS [test], [t4].[Id], [t4].[GroupName]
            FROM [Group] AS [t4]
            ) AS [t5] ON [t3].[GroupId] = ([t5].[Id])
        ) AS [t6]
    ) AS [t7]

Linq to Sql:
var a=from g in Groups
join u in Users
on g.Id  equals u.GroupId
into Grp
from grp in Grp.DefaultIfEmpty()
select new { GroupName=g.GroupName, UserName=(grp==null)?"":grp.UserName};

var b=from u in Users
join g in Groups
on u.GroupId equals g.Id
into Grp
from grp in Grp.DefaultIfEmpty()
select new { GroupName=(grp==null)?"":grp.GroupName, UserName=u.UserName};

var c=a.Concat(b).Distinct();
c.Dump();

Lambda:
Groups
   .GroupJoin (
      Users, 
      g => (Int32?)(g.Id), 
      u => u.GroupId, 
      (g, Grp) => 
         new  
         {
            g = g, 
            Grp = Grp
         }
   )
   .SelectMany (
      temp0 => temp0.Grp.DefaultIfEmpty (), 
      (temp0, grp) => 
         new  
         {
            GroupName = temp0.g.GroupName, 
            UserName = (grp == null) ? "" : grp.UserName
         }
   )
   .Concat (
      Users
         .GroupJoin (
            Groups, 
            u => u.GroupId, 
            g => (Int32?)(g.Id), 
            (u, Grp) => 
               new  
               {
                  u = u, 
                  Grp = Grp
               }
         )
         .SelectMany (
            temp2 => temp2.Grp.DefaultIfEmpty (), 
            (temp2, grp) => 
               new  
               {
                  GroupName = (grp == null) ? "" : grp.GroupName, 
                  UserName = temp2.u.UserName
               }
         )
   )
   .Distinct ()
复制代码


复制代码
Sql:
SELECT [t0].[GroupName], [t1].[UserName]
FROM [Group] AS [t0], [User] AS [t1]

Linq to Sql:
from g in Groups
from u in Users
select new { GroupName=g.GroupName, UserName=u.UserName}

Lambda:
Groups.SelectMany 
(
      g => Users, 
      (g, u) => 
         new  
         {
            GroupName = g.GroupName, 
            UserName = u.UserName
         }
   )
复制代码

 

Linq实现LEFT OUT JOIN

原文地址:http://geekswithblogs.net/AzamSharp/archive/2008/04/07/121103.aspx

Suppose you have a tblRoom and tblUserInfo. Now, you need to select all the rooms regardless of whether the room has user information or not. This calls for a LEFT JOIN which will select everything from the LEFT side (the room side) regardless of the join on the right side. Here is the example.

假如你有两张表tblRoom(房间表)和tblUserInfo(住户表)。现在你需要检索出所有房间的信息,而不管这个房间是否有人居住。这就需要进行LEFT JOIN(左外连接),左外连接会检索出LEFT JOIN左边表中的所有行,而不管右边的表是否有匹配项。下面是一个例子:

var list = from r in dc.tblRooms
                          join ui in dc.tblUserInfos
                          on r.UserName equals ui.UserNameinto userrooms

                          from ur in userrooms.DefaultIfEmpty()

                          select new
                           {
                               FirstName = (ur.FirstName == null) ? "N/A" : ur.FirstName,
                               LastName = (ur.LastName == null) ? "N/A" : ur.LastName,
                               RoomName = r.Name
                           };

The anonymous type replaces the "null" FirstName and LastName with "N/A" (not available).

使用"N/A"(不可得)代替 FirstName 和 LastName 值为"null"的情况。

 

另附:Linq实现多个表 LEFT JOIN 如下

来自:http://hi.baidu.com/xuejianxiyang/item/0c9df0175c8dbdfaddeecae3

目标SQL语句(多表 LEFT JOIN 查询)

[sql] view plain copy
 
  1. 目标SQL语句(多表 LEFT JOIN 查询)  
  2. SELECT id, name, jname, cname   
  3.     FROM userinfo u   
  4.     LEFT JOIN job j on u.job = j.jid   
  5.     LEFT JOIN city c on u.city = c.cid  

Linq To Sql 实现三个表 LEFT JOIN 如下:

[csharp] view plain copy
 
  1. var list = (  
  2. from u in dc.userinfos  
  3.     join j in dc.jobs on u.job equals j.jid into j_join  
  4. from x in j_join.DefaultIfEmpty()  
  5.     join c in dc.cities on u.city equals c.cid into c_join  
  6. from v in c_join.DefaultIfEmpty()  
  7. select new  
  8. {  
  9.     id = u.id,  
  10.     name = u.name,  
  11.     jname = x.jname,  
  12.     cname = v.cname,  
  13.     /*u1=u,x1=x,v1=v*/  
  14.     //不要用对象的方式 因为对象可能为null那么对象.属性就会抛异常  
  15. }  
  16. ).ToList();  
  17.   
  18. for (var i = 0; i < list.Count(); i++)  
  19. {  
  20.     Console.WriteLine(list[i].name + '\t' + list[i].jname + '\t' + list[i].cname); //字段为null不报异常  
  21.     //Console.WriteLine(list[i].u1.name+'\t'+list[i].x1.jname+'\t'+list[i].v1.cname+"\r\n"); //对象x1 v1 有可能为null 抛异常  
  22. }  
  23. Console.ReadLine();  
[csharp] view plain copy
 
  1.    

我用Linq自己写的3个表 LEFT JOIN 例子:

Emp(员工表)、Dept(部门表)、KqEmp(人员考勤信息表)

 
0
posted on 2017-07-08 22:39  不及格的程序员-八神  阅读(18)  评论(0编辑  收藏  举报