有没有办法在Left Join中写一个基于行的条件。
如果根据列条件不存在某行,则应该采用下一个第一行。
我有以下结构,
create table Report
(
id int,
name varchar(10)
)
create table ReportData
(
report_id int references report(id),
flag bit,
path varchar(50)
)
insert into Report values (1, 'a');
insert into Report values (2, 'b');
insert into Report values (3, 'c');
insert into ReportData values (1, 0, 'xx');
insert into ReportData values (2, 0, 'yy');
insert into ReportData values (2, 1, 'yy');
insert into ReportData values (3, 1, 'zz');
insert into ReportData values (3, 1, 'mm');
我需要一些像
这样的输出1 a 0 xx
2 b 0 yy
3 c 1 zz
答案 0 :(得分:1)
您可以使用ROW_NUMBER
:
;WITH ReportDate_Rn AS (
SELECT report_id, flag, path,
ROW_NUMBER() OVER (PARTITION BY report_id ORDER BY path) AS rn
FROM ReportDate
)
SELECT t1.id, t1.name, t2.flag, t2.path
FROM Report AS t1
JOIN ReportDate_Rn AS t2 ON t1.id = t2.report_id AND t2.rn = 1
上述查询视为每个report_id
切片的第一个记录,字母最小 path
。您可以根据需要修改ORDER BY
窗口函数的ROW_NUMBER()
子句。
答案 1 :(得分:0)
SELECT id,name,flag,path
FROM
(
SELECT Report.id,Report.name,ReportData.flag,ReportData.path,
row_number() over(partition by ReportData.report_id order by flag) as rownum
FROM Report
JOIN ReportData on Report.id = ReportData.report_id
) tmp
WHERE tmp.rownum=1
答案 2 :(得分:0)
使用rowid和rownum
的左连接的简单替代方法SELECT id, name, flag, path
FROM report, reportdata
WHERE reportdata.rowid = (SELECT rowid
FROM reportdata
WHERE id = report_id
AND rownum = 1);
答案 3 :(得分:0)
不使用row_numner()
就可以实现这一目标。
看一下 SQL Fiddle
select r.id, r.name, d.flag, d.path from report r
inner join reportdata d
on r.id = d.report_id group by d.report_id
PS:我不相信结果 - 我只是在构建查询 - 未在d.report_id
中使用select clause
并且它有效。一旦得到此查询有效的原因,将更新此答案:)
答案 4 :(得分:0)
使用 Partition BY :
declare @Report AS table
(
id int,
name varchar(10)
)
declare @ReportData AS table
(
report_id int ,
flag bit,
path varchar(50)
)
insert into @Report values (1, 'a');
insert into @Report values (2, 'b');
insert into @Report values (3, 'c');
insert into @ReportData values (1, 0, 'xx');
insert into @ReportData values (2, 0, 'yy');
insert into @ReportData values (2, 1, 'yy');
insert into @ReportData values (3, 1, 'zz');
insert into @ReportData values (3, 1, 'mm');
;WITH T AS
(
Select
R.id,
r.name,
RD.flag,
RD.path,
ROW_NUMBER () OVER(PARTITION BY R.id ORDER BY R.id) AS PartNo
FROM @Report R
LEFT JOIN @ReportData RD ON R.id=RD.report_id
)
SELECT
T.id,
T.name,
T.flag,
T.path
FROM T WHERE T.PartNo=1