如何从tableA中选择一行并加入同一个表

时间:2017-08-10 20:33:09

标签: sql sql-server sql-server-2016

我有一张包含以下内容的表格...... enter image description here

上面的排序依据是:CustomerID,JobType,Book,然后是Page

最终目标是在一个或两个空为空时填充EndBook和EndPage列(在此示例中除了行#15之外的每一行)。目前我只是尝试创建一个SELECT查询,该查询返回下面显示的相同表,但是在EndBook和EndPage列中填写了值。

我期望它发挥作用的方式是......

  • EndBook将等于结果中下一行的Book(按CustomerID,JobType,Book,然后按Page)排序。
    • 例如:ID11将是' ABCD'
    • 例如:ID12将是' ABCD'
    • 例如:ID13将是' ABT5'
    • Ex:ID14将是'' (因为这是typeA的最后一个结果)
    • 例如:ID15将是' 00A1' (单独留下并且不包括在查询中(因为两端都已填写)
    • 例如:ID16将是'' (因为这是typeB的最后一个结果)
    • 例如:ID17将是'' (因为这是客户586的唯一typeC)
    • 例如:ID18将是' 1234'
  • EndPage将等于结果中下一行的Page(按CustomerID,JobType,Book和Page排序时)。
    • 例如:ID11将是' 126'
    • 例如:ID12将是' 150'
    • 例如:ID13将是' 021'
    • Ex:ID14将是'' (因为这是typeA的最后一个结果)
    • 例如:ID15将是' 005' (单独留下并且不包括在查询中(因为两端都已填写)
    • 例如:ID16将是'' (因为这是typeB的最后一个结果)
    • 例如:ID17将是'' (因为这是客户586的唯一typeC)
    • 例如:ID18将是' 013'

我目前有以下查询,但我似乎无法得到我想要的内容。在这最新的尝试中,当我期望它总共返回9(除了1之外)时,它只返回4个结果......

SELECT
    job.CustomerID,
    job.JobType,
    job.Book,
    job.Page,
    job.EndBook,
    job.EndPage,
    next_inst.min_book,
    next_inst.min_page
FROM JobList AS job
INNER JOIN
(
    SELECT
        jl2.CustomerID,
        jl2.JobType,
        MIN(jl3.Book) AS min_book,
        MIN(jl3.Page) AS min_page
    FROM JobList AS jl2
    INNER JOIN
        JobList AS jl3 ON jl3.Book>=jl2.Book AND jl3.Page>jl2.Page
    GROUP BY jl2.CustomerID, jl2.JobType
) AS next_inst ON next_inst.min_book=job.Book AND next_inst.min_page=job.Page
WHERE job.EndBook='' or job.EndPage=''
ORDER BY job.CustomerID, job.JobType, job.Book, job.Page

1 个答案:

答案 0 :(得分:3)

使用lead()窗口函数:

SELECT
    job.CustomerID,
    job.JobType,
    job.Book,
    job.Page,
    job.EndBook,
    job.EndPage,
    nextBook = lead(job.book) over (partition by CustomerId, JobType order by Book, Page),
    nextPage = lead(job.page) over (partition by CustomerId, JobType order by Book, Page)
FROM JobList AS job
ORDER BY job.CustomerID, job.JobType, job.Book, job.Page

要将null更改为空字符串,您可以使用coalesce()isnull()

使用common table expression我们可以将其转换为update

;with cte as (
  select
      job.Customerid,
      job.JobType,
      job.Book,
      job.Page,
      job.EndBook,
      job.EndPage,
      nextBook = lead(job.book) over (partition by CustomerId, JobType order by Book, Page),
      nextPage = lead(job.page) over (partition by CustomerId, JobType order by Book, Page)
  from JobList as job
)
update cte
  set EndBook = coalesce(nextBook,'')
    , EndPage = coalesce(nextPage,'')
where EndBook = ''
   or EndPage = '';