我在PostgreSQL中的查询显示了一段时间内的会议:start_date和:end_date。
问题在于“ktore”列,它表明会议是第一次。我使用“内部联接”来添加子查询,该子查询在公司中计算我的会议,如果 count> 1 ,然后写“next”,否则 - “first”。但它仅在上次会议日期显示正确的结果。让我举个例子:
在Company1有两次会议 - 2017-09-02会议1和2017-09-05会议2。
如果我选择:开始日期到2017-09-01和:end_date 到2017-09-06,那么我的查询显示:
id company_name audit_date nip ktore
...
234 Company1 2017-09-02 1234567 NEXT
...
287 Company1 2017-09-05 1234567 NEXT
但我想要这个:
id company_name audit_date nip ktore
...
234 Company1 2017-09-02 1234567 FIRST
...
287 Company1 2017-09-05 1234567 NEXT
那么我应该在查询中做些什么呢?
select a.id, a.company_name, to_char(a.audit_date,'YYYY-MM-DD hh:mi') audit_date, companys.nip,
case
when b.costam > 1 then 'NEXT'
else 'FIRST'
end ktore
from companys, meetings a
inner join (select company_id, count(1) costam from meetings where status !='CANCELED' and status !='SUSPENDED'
and to_char(audit_dc,'YYYY-MM-DD')<= :end_date group by company_id) b on a.company_id = b.company_id
where to_char(a.audit_date,'YYYY-MM-DD')>= :start_date
and to_char(a.audit_date,'YYYY-MM-DD')<= :end_date and companys.id = a.company_id
我认为写一些类似“如果公司存在与早期日期会议,然后”NEXT“,否则”FIRST“会很好,但我不知道代码是如何做的。
提前谢谢你, Mateusz
答案 0 :(得分:1)
尝试以下查询即可。我的逻辑是,从子查询中我最少使用audit_date,然后与主表审核日期进行比较,如果匹配,那么它将给出第一个其他NEXT,如果有一个companyId有3个不同的日期,那么它将为最小日期提供FIRST和剩下的日期
select a.id, a.company_name, to_char(a.audit_date,'YYYY-MM-DD hh:mi') audit_date, companys.nip,
case
when b.costam >1 and min_audit_date=a.audit_date then 'FIRST'
else 'NEXT'
end ktore
from companys, meetings a
inner join (select company_id, count(1) costam,min(audit_date) min_audit_date,max(audit_date) max_audit_date from meetings where status !='CANCELED' and status !='SUSPENDED'
and to_char(audit_dc,'YYYY-MM-DD')<= :end_date group by company_id) b on a.company_id = b.company_id
where to_char(a.audit_date,'YYYY-MM-DD')>= :start_date
and to_char(a.audit_date,'YYYY-MM-DD')<= :end_date and companys.id = a.company_id
如果你的逻辑与我上面所做的相反,你可以改变逻辑 max_audit_date
答案 1 :(得分:0)
您正在做的事情会起作用,但更惯用的做法是使用Windowing Functions之类的内容,可能使用ROW_NUMBER()
:
SELECT Meetings.id, Meetings.company_name,
TO_CHAR(Meetings.audit_date, 'YYYY-MM-DD hh:mi') AS audit_date,
Companys.nip,
CASE WHEN ROW_NUMBER() OVER(PARTITION BY Meetings.company_id
ORDER BY Meetings.audit_date) = 1
THEN 'FIRST'
ELSE 'NEXT'
END AS ktore
FROM Meetings
JOIN Companys
ON Companys.id = Meetings.company_id
WHERE Meetings.status NOT IN ('CANCELED', 'SUSPENDED')
AND Meetings.audit_date >= TIMESTAMP :startDate
AND Meetings.audit_date < TIMESTAMP :endDate
ORDER BY Meetings.company_id, Meetings.audit_date
您会注意到您的查询中发生了许多变化。我还有其他一些想法。
Meetings.company_name
- 我很难相信该列位于该表中,它可能更应该是Companys.company_name
。Companies
,但是关于表名是否应该是单数而不是复数的争论很多。'FIRST'
,这可能不是同一回事。目前还不清楚你真正想要的是什么。