我有一个与客户的“table-a”和一个与客户联系的“table-b”。我想选择每个客户并显示上次“通过电话与客户联系”和最后一次“客户访问”,以及一些< strong>来自table-b的信息。
表格设计如下:
number (PK) Name Adress
101 Bob Street 1
102 Peter Street
number (PK) c-nr (FK) type date free text
11111 101 visit 01.08.2016 text3
11112 101 visit 20.08.2016 text2
11113 102 phone 15.09.2016 text1
11113 102 email 15.09.2016 text1
Number Name Adress Last Visit Visit Text Last-Call Call-Text
101 Bob Street 1 20.08.2016 text2 NONE NONE
102 Peter Street 2 NONE NONE 15.09.206 text1
select
a.number
,a.name
,a.adress
,last-visit.date
,last-call.date
from table-a as a
left join
(select
inner-b.c-nr as customer-number
,max(inner-b.date) as date
from table-b as inner-b
where
type = 'visit'
group by innner-b.c-nr) as last-visit on last-visit.customer-number = a.number
left join
(select
inner-b.c-nr as customer-number
,max(inner-b.date) as date
from table-b as inner-b
where
type = 'phone'
group by inner-b.c-nr) as last-call on last-call.customer-number = a.number
它可以显示我最后一次访问和最后一次调用,但我无法达到我可以添加文本的程度,因为如果我添加其他字段(即主键或文本本身) )在内部选择它会搞砸组。此外,我不确定这是“好SQL”。
有什么建议吗?
答案 0 :(得分:2)
您可以使用OUTER APPLY获取最新的visit
,phone
事件:
SELECT a.number,
a.[Name],
a.Adress,
CASE WHEN b.[type] = 'visit' THEN b.[date] ELSE NULL END as [Last Visit],
CASE WHEN b.[type] = 'visit' THEN b.[free text] ELSE NULL END as [Visit Text],
CASE WHEN c.[type] = 'phone' THEN c.[date] ELSE NULL END as [Last-Call],
CASE WHEN c.[type] = 'phone' THEN c.[free text] ELSE NULL END as [Call-Text]
FROM tableA a
OUTER APPLY (
SELECT TOP 1 *
FROM TableB
WHERE [c-nr] = a.number and [type] IN ('visit' )
ORDER BY [date] desc
) b
OUTER APPLY (
SELECT TOP 1 *
FROM TableB
WHERE [c-nr] = a.number and [type] IN ('phone')
ORDER BY [date] desc
) c
您提供的样本的输出:
number Name Adress Last Visit Visit Text Last-Call Call-Text
101 Bob Street 1 20.08.2016 text2 NULL NULL
102 Peter Street NULL NULL 15.09.2016 text1
答案 1 :(得分:1)
你生活中需要row_number:
select a.number,
a.name,
a.Address,
b.date as CallDate,
b.freetext as CallNotes,
c.date as VisitDate,
c.freetext as VisitNotes
from TableA a
left join
(
select c_nr, date, freetext, row_number() over(partition by c_nr order by date desc) as Call_Ord
from TableB
where type = 'Phone'
) b
on a.number = b.c_nr
and b.Call_Ord = 1
left join
(
select c_nr, date, freetext, row_number() over(partition by c_nr order by date desc) as Call_Ord
from TableB
where type = 'Visit'
) c
on a.number = c.c_nr
and c.Vis_Ord = 1
答案 2 :(得分:1)
WITH lastVisit as (
SELECT [c-nr], date, [free text],
row_number() over (partition by [c-nr] order by [date] desc) rn
FROM table_b
WHERE type = 'visit'
), lastCall as (
SELECT [c-nr], date, [free text],
row_number() over (partition by [c-nr] order by [date] desc) rn
FROM table_b
WHERE type = 'phone'
)
SELECT ta.[number], ta.Name, ta.[Adress],
COALESCE(lv.date, 'NONE') as [Last Visit],
COALESCE(lv.[free text], 'NONE') as [Visit Text],
COALESCE(lc.date, 'NONE') as [Last Call],
COALESCE(lc.[free text], 'NONE') as [Call Text]
FROM table_a ta
LEFT JOIN lastVisit lv
ON ta.[number] = lv.[c-nr]
AND lv.rn = 1
LEFT JOIN lastCall lc
ON ta.[number] = lc.[c-nr]
AND lc.rn = 1
<强>输出强>