I have 3 tables in my database - Quarter
, Organization
, History
and I'm using Dynamics CRM to store my data.
Quarter
columns :
Organization
columns:
History
columns:
I'd like to construct the following SQL query: Retrieve all History
records per Quarter
and Organization
whose create-date
value is last created.
For example in History
table:
| guid | organization | cert | calc | create-date | quarter
| 1 | org1 | 2 | 2.5 | 2021-07-06 00:00:00 | Q3 2021
| 2 | org2 | 2 | NULL | 2021-07-25 00:00:00 | Q3 2021
| 3 | org3 | 3 | NULL | 2021-07-25 00:00:00 | Q3 2021
| 4 | org1 | 3 | NULL | 2021-08-01 00:00:00 | Q3 2021
| 5 | org1 | 3 | NULL | 2021-08-01 00:00:00 | Q3 2021
| 6 | org1 | 3 | NULL | 2021-09-15 00:00:00 | Q3 2021
| 7 | org1 | 2 | 2.25 | 2021-11-18 00:00:00 | Q4 2021
Query should return the following records: (minus the guid column)
| guid | organization | cert | calc | create-date | quarter | year
| 2 | org2 | 2 | NULL | 2021-07-25 00:00:00 | Q3 | 2021
| 3 | org3 | 3 | NULL | 2021-07-25 00:00:00 | Q3 | 2021
| 6 | org1 | 3 | NULL | 2021-09-15 00:00:00 | Q3 | 2021
| 7 | org1 | 2 | 2.25 | 2021-11-18 00:00:00 | Q4 | 2021
My query :
SELECT
QTR.new_year AS [year],
CASE
WHEN QTR.new_quarter = 100000000 THEN 'Q1'
WHEN QTR.new_quarter = 100000001 THEN 'Q2'
WHEN QTR.new_quarter = 100000002 THEN 'Q3'
ELSE 'Q4'
END AS [quarter],
/* FORMAT(HISTORY.new_calc, 'N2') AS [calc],
HISTORY.new_cert AS [cert], */
MAX(HISTORY.new_create_date) AS [create-date],
ORG.new_name AS [org]
FROM
dbo.new_quarterBase AS QTR
INNER JOIN
dbo.new_historyBase AS HISTORY ON QTR.new_quarterId = HISTORY.new_quarter
INNER JOIN
dbo.new_organizationBase AS ORG ON HISTORY.new_organization = ORG.new_organizationId
GROUP BY
QTR.new_quarter, QTR.new_year, ORG.new_name
The query works fine, but I'd like the query to also return the commented-out columns and I don't want them to be in the GROUP BY
clause.
How can I solve this problem?
I'd like to construct the following SQL query: Retrieve all History records per Quarter and Organization whose create-date value is last created.
I don't know wha the underlying database is for Dynamics CRM, but the way to do this in SQL uses row_number()
or rank()
:
SELECT qh.*
FROM (SELECT q.new_year AS [year],
(CASE WHEN q.new_quarter = 100000000 THEN 'Q1'
WHEN q.new_quarter = 100000001 THEN 'Q2'
WHEN q.new_quarter = 100000002 THEN 'Q3'
ELSE 'Q4'
END) AS [quarter],
FORMAT(h.new_calc, 'N2') AS [calc],
h.new_cert AS [cert],
h.new_create_date,
o.new_name AS org,
RANK() OVER (PARTITION BY q.new_quarter, q.new_year, o.new_name ORDER BY h.new_create_date DESC) as seqnum
FROM dbo.new_quarterBase q JOIN
dbo.new_historyBase h
ON q.new_quarterId = h.new_quarter JOIN
dbo.new_organizationBase o
ON h.new_organization = o.new_organizationId
) qh
WHERE seqnum = 1;
The difference between row_number()
and rank()
is that the latter returns all history records in a quarter if there are ties for the most recent. The former returns only one.