sql-server – 在哪里使用外部应用

前端之家收集整理的这篇文章主要介绍了sql-server – 在哪里使用外部应用前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
主表
  1. x------x--------------------x
  2. | Id | Name |
  3. x------x--------------------x
  4. | 1 | A |
  5. | 2 | B |
  6. | 3 | C |
  7. x------x--------------------x

详细信息表

  1. x------x--------------------x-------x
  2. | Id | PERIOD | QTY |
  3. x------x--------------------x-------x
  4. | 1 | 2014-01-13 | 10 |
  5. | 1 | 2014-01-11 | 15 |
  6. | 1 | 2014-01-12 | 20 |
  7. | 2 | 2014-01-06 | 30 |
  8. | 2 | 2014-01-08 | 40 |
  9. x------x--------------------x-------x

当使用LEFT JOIN和OUTER APPLY时,我得到相同的结果.

LEFT JOIN

  1. SELECT T1.ID,T1.NAME,T2.PERIOD,T2.QTY
  2. FROM MASTER T1
  3. LEFT JOIN DETAILS T2 ON T1.ID=T2.ID

外部申请

  1. SELECT T1.ID,TAB.PERIOD,TAB.QTY
  2. FROM MASTER T1
  3. OUTER APPLY
  4. (
  5. SELECT ID,PERIOD,QTY
  6. FROM DETAILS T2
  7. WHERE T1.ID=T2.ID
  8. )TAB

我应该在哪里使用LEFT JOIN以及我应该在哪里使用OUTER APPLY

解决方法

在以下情况下,应使用OUTER APPLY替换LEFT JOIN.

1.如果我们想根据TOP n结果加入两个表

考虑我们是否需要从Master中选择Id和Name,并从Details表中为每个Id选择最后两个日期.

  1. SELECT M.ID,M.NAME,D.PERIOD,D.QTY
  2. FROM MASTER M
  3. LEFT JOIN
  4. (
  5. SELECT TOP 2 ID,QTY
  6. FROM DETAILS D
  7. ORDER BY CAST(PERIOD AS DATE)DESC
  8. )D
  9. ON M.ID=D.ID

形成以下结果

  1. x------x---------x--------------x-------x
  2. | Id | Name | PERIOD | QTY |
  3. x------x---------x--------------x-------x
  4. | 1 | A | 2014-01-13 | 10 |
  5. | 1 | A | 2014-01-12 | 20 |
  6. | 2 | B | NULL | NULL |
  7. | 3 | C | NULL | NULL |
  8. x------x---------x--------------x-------x

这将带来错误的结果,即,即使我们加入Id,它也只会从详细信息表中带来最新的两个日期数据而不管Id.所以正确的解决方案是使用OUTER APPLY.

  1. SELECT M.ID,D.QTY
  2. FROM MASTER M
  3. OUTER APPLY
  4. (
  5. SELECT TOP 2 ID,QTY
  6. FROM DETAILS D
  7. WHERE M.ID=D.ID
  8. ORDER BY CAST(PERIOD AS DATE)DESC
  9. )D

这是工作:在LEFT JOIN中,只有在派生表D中执行查询后,才会将TOP 2日期加入MASTER.在OUTER APPLY中,它使用在OUTER APPLY中加入WHERE M.ID = D.ID,这样Master中的每个ID都将与TOP 2日期相结合,这将带来以下结果.

  1. x------x---------x--------------x-------x
  2. | Id | Name | PERIOD | QTY |
  3. x------x---------x--------------x-------x
  4. | 1 | A | 2014-01-13 | 10 |
  5. | 1 | A | 2014-01-12 | 20 |
  6. | 2 | B | 2014-01-08 | 40 |
  7. | 2 | B | 2014-01-06 | 30 |
  8. | 3 | C | NULL | NULL |
  9. x------x---------x--------------x-------x

2.当我们需要使用函数的LEFT JOIN功能时.

当我们需要从主表和函数获取结果时,OUTER APPLY可以用作LEFT JOIN的替换.

  1. SELECT M.ID,C.PERIOD,C.QTY
  2. FROM MASTER M
  3. OUTER APPLY dbo.FnGetQty(M.ID) C

功能就在这里.

  1. CREATE FUNCTION FnGetQty
  2. (
  3. @Id INT
  4. )
  5. RETURNS TABLE
  6. AS
  7. RETURN
  8. (
  9. SELECT ID,QTY
  10. FROM DETAILS
  11. WHERE ID=@Id
  12. )

产生了以下结果

  1. x------x---------x--------------x-------x
  2. | Id | Name | PERIOD | QTY |
  3. x------x---------x--------------x-------x
  4. | 1 | A | 2014-01-13 | 10 |
  5. | 1 | A | 2014-01-11 | 15 |
  6. | 1 | A | 2014-01-12 | 20 |
  7. | 2 | B | 2014-01-06 | 30 |
  8. | 2 | B | 2014-01-08 | 40 |
  9. | 3 | C | NULL | NULL |
  10. x------x---------x--------------x-------x

3.在取消隐藏时保留NULL值

考虑一下你有下表

  1. x------x-------------x--------------x
  2. | Id | FROMDATE | TODATE |
  3. x------x-------------x--------------x
  4. | 1 | 2014-01-11 | 2014-01-13 |
  5. | 1 | 2014-02-23 | 2014-02-27 |
  6. | 2 | 2014-05-06 | 2014-05-30 |
  7. | 3 | NULL | NULL |
  8. x------x-------------x--------------x

当您使用UNPIVOT将FROMDATE和TODATE带到一列时,它将默认消除NULL值.

  1. SELECT ID,DATES
  2. FROM MYTABLE
  3. UNPIVOT (DATES FOR COLS IN (FROMDATE,TODATE)) P

产生以下结果.请注意,我们错过了身份证号码3的记录

  1. x------x-------------x
  2. | Id | DATES |
  3. x------x-------------x
  4. | 1 | 2014-01-11 |
  5. | 1 | 2014-01-13 |
  6. | 1 | 2014-02-23 |
  7. | 1 | 2014-02-27 |
  8. | 2 | 2014-05-06 |
  9. | 2 | 2014-05-30 |
  10. x------x-------------x

在这种情况下,可以使用APPLY(CROSS APPLY或OUTER APPLY,可以互换).

  1. SELECT DISTINCT ID,DATES
  2. FROM MYTABLE
  3. OUTER APPLY(VALUES (FROMDATE),(TODATE))
  4. COLUMNNAMES(DATES)

形成以下结果并保留其值为3的Id

  1. x------x-------------x
  2. | Id | DATES |
  3. x------x-------------x
  4. | 1 | 2014-01-11 |
  5. | 1 | 2014-01-13 |
  6. | 1 | 2014-02-23 |
  7. | 1 | 2014-02-27 |
  8. | 2 | 2014-05-06 |
  9. | 2 | 2014-05-30 |
  10. | 3 | NULL |
  11. x------x-------------x

猜你在找的MsSQL相关文章