I am a novice trying to work through this here with no luck so far, any help is greatly appreciated!!!
Select Distinct
(AB.agency_no || '-' || ab.branch_no) AS "AGENCY-BRANCH",
count (AB.agency_no || '-' || ab.branch_no) AS Occurences,
A.AGY_NAME AS AGENCY,
Sum(AB.annual_premium) as Premium
From Agency_Book_View AB, Agency A, Branch B
Where AB.agency_no = A.Agency_No
AND B.EXPIRATION_DATE = TO_DATE('12-31-2078', 'MM-DD-YYYY')
AND B.EFFECTIVE_DATE <= sysdate and b.effective_date >=sysdate - 364
Group by AB.agency_no || '-' || ab.branch_no, A.Agy_Name, ab.annual_premium
Order by AB.agency_no || '-' || ab.branch_no
So I am trying to return total annual premium per "agency-branch" and I am getting multiple occurrences of agency-branch. I am trying to get one line per agency branch. I hope this is clear. I tried to include a result set but wasnt allowed to include a picture in my post.
Thanks very much!
Brad
Try this :
SELECT (AB.agency_no || '-' || AB.branch_no) AS "AGENCY-BRANCH",
COUNT(AB.agency_no || '-' || AB.branch_no) AS Occurences,
A.AGY_NAME AS AGENCY,
SUM(AB.annual_premium) AS Premium
FROM Agency_Book_View AB, Agency A, Branch B
WHERE AB.agency_no = A.Agency_No AND AB.branch_no = B.branch_no
AND B.EXPIRATION_DATE = TO_DATE('12-31-2078', 'MM-DD-YYYY')
AND B.EFFECTIVE_DATE <= SYSDATE AND B.effective_date >= SYSDATE - 364
GROUP BY AB.agency_no || '-' || AB.branch_no, A.Agy_Name
ORDER BY AB.agency_no || '-' || AB.branch_no
I joined B table and AB table, removed the DISTINCT and the GROUPed BY ab.annual_premium.
I think you need to remove ab.annual_premium from the group by clause.
Related
Consider Table Events
Date Time Duration Event
1-1-2023 20:28:00 95 A
1-1-2023 20:29:00 60 B
1-1-2023 20:29:55 10 C
1-1-2023 21:12:00 2 D
...
Now i want to get entries happening in same time period, so for example activity A happens from 20:28:00 to 20:29:35, and activity B happens in time period of 20:29:00 to 20:30:00
So Event A and B have common 35 seconds and B and C has common 5 secs.
i want to get all events in common time period, is it possible using just sql query?
Assuming that your dates are in the proper ISO format YYYY-MM-DD, you can use a self join:
SELECT *
FROM events e1 INNER JOIN events e2
ON e2.event > e1.event
AND datetime(e2.date || ' ' || e2.time, e2.duration || ' second') > e1.date || ' ' || e1.time
AND e2.date || ' ' || e2.time < datetime(e1.date || ' ' || e1.time, e1.duration || ' second');
See the demo.
Maybe, supposing you have index on date-time
SELECT *
FROM events e1 INNER JOIN events e2
ON datetime(e2.date || ' ' || e2.time)
BETWEEN (e1.date || ' ' || e1.time)
AND datetime(e1.date || ' ' || e1.time, e1.duration || ' second')
WHERE e2.event <> e1.event;
As #forpas says, if you kept date an time values in a single column, and have index on this column, performance will be better
My goal is to choose the PTID with the most recent date with its recent time. I was trying to use the MAX() function to choose the most recent date with its recent time but received an error syntax (see the double asterisk on Line 9 in my code). Is there a statement to do that or would it be easier to do it in Python? I appreciate all the help!
Table 1
PTID
RESULT_DATE1
RESULT_TIME
DIAGNOSIS_CD
54
2020-01-06
10:03:02
W34
54
2020-01-01
09:18:05
S38
54
2020-01-01
03:08:45
V98
54
2020-04-04
02:09:08
V98
54
2020-04-04
12:12:34
V89
My Goal:
PTID
RESULT_DATE1
RESULT_TIME
DIAGNOSIS_CD
54
2020-04-04
12:12:34
V98
54
2020-01-06
10:03:02
W34
54
2020-01-01
09:18:05
S38
My Code:
CREATE TABLE covid AS
SELECT t1.*, t2.*
FROM lab9 t1 JOIN diagnosis9 t2 ON t2.PTID = t1.PTID
AND t1.RESULT_DATE1 || ' ' || t1.RESULT_TIME
BETWEEN
date(t2.diagdate1, '-7 day') || ' ' || t2.DIAG_TIME
AND
t2.diagdate1 || ' ' || t2.DIAG_TIME
**WHERE RESULT_DATE1 = MAX(RESULT_DATE1)**
GROUP BY t1.PTID || DIAGNOSIS_CD
ORDER BY t1.PTID;
First, you should not group by the concatenation of 2 columns because this may lead to unexpected results.
You should group by the 2 columns.
Also, you can't use an aggregate function like MAX() in the WHERE clause of a query.
What you need is the max value of the expression t1.RESULT_DATE1 || ' ' || t1.RESULT_TIME which you can finally split to date and time with the functions date() and time():
CREATE TABLE covid AS
SELECT t1.PTID,
date(MAX(t1.RESULT_DATE1 || ' ' || t1.RESULT_TIME)) RESULT_DATE1,
time(MAX(t1.RESULT_DATE1 || ' ' || t1.RESULT_TIME)) RESULT_TIME,
t2.*
FROM lab9 t1 JOIN diagnosis9 t2
ON t2.PTID = t1.PTID
AND t1.RESULT_DATE1 || ' ' || t1.RESULT_TIME
BETWEEN
date(t2.diagdate1, '-7 day') || ' ' || t2.DIAG_TIME AND t2.diagdate1 || ' ' || t2.DIAG_TIME
GROUP BY t1.PTID, t2.DIAGNOSIS_CD
ORDER BY t1.PTID;
The above query will return the rows with the max datetime for each combination of PTID and DIAGNOSIS_CD with the use if SQLite's feature of bare columns.
I am trying to create an SQL query to select percentage utilization for my team members.
I am looking for a to daily basis select query to show the utilization when it is greater than 0 and to show '0' when it is null. In order to be able to plot those figures later on as a line chart.
I have written 365 of the following select query and I have combined them together using "UNION ALL" method. It is working now, but it is extremely slow!.
If you have a better idea to produce the daily outputs for the 365 days, that will be great.
Many thanks in advance.
Kind regards
Mohamed
Code:
.........................
SELECT ifnull((
SELECT SUM(CAST(pc_loading.value AS INT))
FROM ticket
JOIN ticket_custom start_date ON (ticket.id = start_date.ticket AND start_date.name = 'planned_start_date')
JOIN ticket_custom finish_date ON (ticket.id = finish_date.ticket AND finish_date.name = 'planned_finish_date')
JOIN ticket_custom pc_loading ON (ticket.id = pc_loading.ticket AND pc_loading.name = 'percentage_loading')
WHERE UPPER(ticket.owner)='#########'
AND ticket.type = 'Internal Resource'
AND DATE(substr(start_date.value, 7, 4) || '-' || substr(start_date.value, 4, 2) || '-' || substr(start_date.value, 1, 2)) <= DATE('2020-01-01')
AND DATE(substr(finish_date.value, 7, 4) || '-' || substr(finish_date.value, 4, 2) || '-' || substr(finish_date.value, 1, 2)) >= DATE('2020-01-01')
AND status NOT IN ("closed", "suspended")) , 0) UNION ALL
SELECT ifnull((
SELECT SUM(CAST(pc_loading.value AS INT))
FROM ticket
JOIN ticket_custom start_date ON (ticket.id = start_date.ticket AND start_date.name = 'planned_start_date')
JOIN ticket_custom finish_date ON (ticket.id = finish_date.ticket AND finish_date.name = 'planned_finish_date')
JOIN ticket_custom pc_loading ON (ticket.id = pc_loading.ticket AND pc_loading.name = 'percentage_loading')
WHERE UPPER(ticket.owner)='#########'
AND ticket.type = 'Internal Resource'
AND DATE(substr(start_date.value, 7, 4) || '-' || substr(start_date.value, 4, 2) || '-' || substr(start_date.value, 1, 2)) <= DATE('2020-01-02')
AND DATE(substr(finish_date.value, 7, 4) || '-' || substr(finish_date.value, 4, 2) || '-' || substr(finish_date.value, 1, 2)) >= DATE('2020-01-02')
AND status NOT IN ("closed", "suspended")) , 0) UNION ALL
.......etc
....................................
Use a recursive CTE which returns all the dates of 2020, cross join it to your query and group by each date:
with recursive days as (
select date('2020-01-01') date
union all
select date(date, '+1 day')
from days
where strftime('%Y', date, '+1 day') = '2020'
)
SELECT days.date, COALESCE(SUM(CAST(pc_loading.value AS INT)), 0)
FROM days
CROSS JOIN ticket
JOIN ticket_custom start_date ON (ticket.id = start_date.ticket AND start_date.name = 'planned_start_date')
JOIN ticket_custom finish_date ON (ticket.id = finish_date.ticket AND finish_date.name = 'planned_finish_date')
JOIN ticket_custom pc_loading ON (ticket.id = pc_loading.ticket AND pc_loading.name = 'percentage_loading')
WHERE UPPER(ticket.owner)='#########' AND ticket.type = 'Internal Resource'
AND DATE(substr(start_date.value, 7, 4) || '-' || substr(start_date.value, 4, 2) || '-' || substr(start_date.value, 1, 2)) <= days.date
AND DATE(substr(finish_date.value, 7, 4) || '-' || substr(finish_date.value, 4, 2) || '-' || substr(finish_date.value, 1, 2)) >= days.date
AND status NOT IN ("closed", "suspended")
GROUP BY days.date
Also, you would find significant improvement in performance if you stored the dates in a comparable format like YYYY-MM-DD since there would be no need for all these rearrangements/concatenations in the WHERE clause.
Alternative without the use of the CTE:
SELECT days.date, COALESCE(SUM(CAST(pc_loading.value AS INT)), 0)
FROM (
SELECT '2020-01-01' date UNION ALL SELECT '2020-01-02' UNION ALL
SELECT '2020-01-03' UNION ALL SELECT '2020-01-04' UNION ALL
............................................................
) days
CROSS JOIN ticket
JOIN ticket_custom start_date ON (ticket.id = start_date.ticket AND start_date.name = 'planned_start_date')
JOIN ticket_custom finish_date ON (ticket.id = finish_date.ticket AND finish_date.name = 'planned_finish_date')
JOIN ticket_custom pc_loading ON (ticket.id = pc_loading.ticket AND pc_loading.name = 'percentage_loading')
WHERE UPPER(ticket.owner)='#########' AND ticket.type = 'Internal Resource'
AND DATE(substr(start_date.value, 7, 4) || '-' || substr(start_date.value, 4, 2) || '-' || substr(start_date.value, 1, 2)) <= days.date
AND DATE(substr(finish_date.value, 7, 4) || '-' || substr(finish_date.value, 4, 2) || '-' || substr(finish_date.value, 1, 2)) >= days.date
AND status NOT IN ("closed", "suspended")
GROUP BY days.date
In my application each manager has a work pattern (for example Monday-Friday). But I also have a table "pattern_changes" where they can insert data if they cannot be present at work.
With the first query I can show who is available today, according to the pattern assigned to them:
SELECT distinct gu.first_name || ' ' || gu.last_name
FROM patterns pa JOIN fmanager_pattern fp
ON pa.id = fp.pattern_id
JOIN fmanagers fm
ON fm.id = fp.fmanager_id
JOIN gen_users gu
ON gu.user_id = fm.user_id
WHERE (TO_CHAR(pa.start_dt, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') LIKE TO_CHAR(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AND pa.start_dt < sysdate and pa.end_dt > sysdate)
OR (TO_CHAR(pa.end_dt, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') LIKE TO_CHAR(sysdate, 'DY', 'NLS_DATE_LANGUAGE=ENGLISH') AND pa.start_dt < sysdate and pa.end_dt > sysdate)
OR TO_CHAR(sysdate, 'D') BETWEEN TO_CHAR(pa.start_dt, 'D') AND TO_CHAR(pa.end_dt, 'D') AND pa.start_dt < sysdate and pa.end_dt > sysdate
OR TO_CHAR(sysdate, 'D')+7 BETWEEN TO_CHAR(pa.start_dt, 'D') AND TO_CHAR(pa.start_dt, 'D')+7 AND pa.start_dt < sysdate and pa.end_dt > sysdate
In the second query I can show who is not available today, according to the pattern_changes table.
SELECT fm.id, gu.first_name || ' ' || gu.last_name
FROM fmanagers fm JOIN pattern_changes pc
ON pc.fmanagers_id = fm.id
JOIN gen_users gu
ON gu.user_id = fm.user_id
WHERE pc.change_dt < sysdate and pc.end_dt > sysdate
OR pc.change_dt = to_char(sysdate)
OR pc.end_dt = to_char(sysdate))
For example, the first query returns: ADAM and EVA
The second query returns ADAM
So I just want to see EVA as a result.
I tried to do it with NOT IN or NOT EXISTS but neither of them work.
Can anybody help?
Thank you in advance
I have a table with details of sold cars. Some of these cars have been resold within last 1, 2 or 3 years. The table looks like this:
Car_Type || Car_Reg_No || Sold_Date || Listing_No
Hatch || 23789 || 2017-02-03 11:26 || X6529
Coupe || 16723 || 2016-11-07 09:40 || N8156
Sedan || 35216 || 2016-05-23 10:34 || M8164
Hatch || 23789 || 2016-09-16 04:30 || O7361
Now, I need to query records (cars) which were re-sold within 1 year of their latest sold date and how many times were they sold. So, my output would be like this:
Car_Type || Car_Reg_No || Sold_Count || Latest_Sold_Date
Hatch || 23789 || 2 || 2017-02-03 11:26
In essence, How do I check for re-sold records within a specific time frame of their latest sold date?
You can do this by finding the max, and joining based on your conditions.
declare #TableA table (Car_Type varchar(64)
,Car_Reg_No int
,Sold_Date datetime
,Listing_No varchar(6))
insert into #TableA
values
insert into #TableA
values
('Hatch',23789,'2017-02-03 11:26','X6529'),
('Coupe',16723,'2017-11-07 09:40','N8156'),
('Sedan',35216,'2017-05-23 10:34','M8164'),
('Hatch',23789,'2016-09-16 04:30','O7361'),
('Coupe',16723,'2014-11-07 09:40','N8156')
;with cte as(
select
Car_Type
,Car_Reg_No
,Latest_Sold_Date = max(Sold_Date)
from
#TableA
group by
Car_Type
,Car_Reg_No)
select
a.Car_Type
,a.Car_Reg_No
,Sold_Count = count(b.Listing_No) + 1
,a.Latest_Sold_Date
from cte a
inner join
#TableA b on
b.Car_Reg_No = a.Car_Reg_No
and b.Sold_Date != a.Latest_Sold_Date
and datediff(day,b.Sold_Date,a.Latest_Sold_Date) < 366
--if you want only cars which were sold within last year too, uncomment this
--and datediff(day,a.Latest_Sold_Date,getdate()) < 366
group by
a.Car_Type
,a.Car_Reg_No
,a.Latest_Sold_Date
By my understanding..,
select sd1.Car_Type, sd1.Car_Reg_No,
count(sd1.Car_Reg_No) + 1 'no of sales in last one year', --1 is added because, see the last condition
sd1.Sold_Date 'Last sold date'
from(
select *,ROW_NUMBER() over(partition by Car_Reg_No order by sold_date desc) as rn from #Table) as sd1
join
(select * from #Table) as sd2
on sd1.Car_Type = sd2.Car_Type
and DATEDIFF(dd,sd2.Sold_Date,sd1.Sold_Date) < 366
and sd1.rn = 1
and sd1.Sold_Date <> sd2.Sold_Date -- here last sold is eliminated. so count is added by one.
group by sd1.Car_Type,sd1.Sold_Date, sd1.Car_Reg_No
order by sd1.Car_Reg_No