I am working on a query where I am trying to pull the minimum date where the owner contains WF in the table.
Table is similar to below:
Order Number
Create Date
Modified Date
Owner
for every order, I need to pull where the minimum modified date where the owner contains %WF%.
Any help would be greatly appreciated.
Thanks.
Here is the query that I have:
select distinct (ol.order_no),
min(os.assgn_dt) as MinDate,
ow.owner_desc,
ol.created_Date,
md.media_type_desc,
ow.owner_desc,
st.status_type_Desc,
os.comment,
tt.team_type_desc,
br.sdescrip as Branch,
ol.bgrp_cnt
from order_log ol
join activity_type att on ol.activity_type_id = att.activity_type_id
join branches br on ol.branch = br.lbranch
join regions rg on br.lregion = rg.lregion
join businessunit bu on rg.lbusinessunit = bu.lbusinessunit
join vwCurrentStatus vcs on vcs.order_no = ol.order_no
join order_status os on os.order_no = vcs.order_no
join owner ow on os.owner_name = ow.owner_id
join status_type st on st.status_type_id = os.status_type_id
join team_type tt on ow.team_type_id = tt.team_type_id
join media_type md on ol.media_type_id = md.media_type_id
join rep_name_xref rnx on rnx.order_no = ol.order_no
join rep_names rn on rn.user_id = rnx.user_id
where ow.owner_desc like '%WF%'
and ol.created_date > '01-01-2012'
and att.activity_type_id in ('14','16')
and tt.team_type_desc in ('1-10 Membership Team','government')
group by ol.order_no, ow.owner_desc, ol.created_Date,md.media_type_desc,ow.owner_desc,st.status_type_Desc, os.comment, tt.team_type_desc,br.sdescrip, ol.bgrp_cnt
Something like:
select order_number,min(modified_date) from orders where owner like '%WF%' group by order_number;
If you want the minimum order date for all orders where the owner contains 'WF', try:
SELECT MIN(ModifiedDate)
FROM MyTable
WHERE Owner like '%WF%'
Regarding what you said in the comments, try this:
SELECT t.Owner, t.ModifiedDate
FROM tablename t
WHERE t.ModifiedDate = (SELECT MIN(t2.ModifiedDate)
FROM tablename t2
WHERE t2.Owner like '%WF%')
It will give you the list of Owners that have the ModifiedDate equal to the Min(ModifiedDate) from a Owner with '%WF%'.
Related
I have a query with many joins and I am trying to select the latest client record from it. This is the query I have but it is giving me all records of the client:
EDIT:
SELECT ca.CA_ID, ca.CLIENT_ID, ca.CA_STATUS_TYPE, ca.CREATED_BY, MAX(ca.CREATED_DATE), ca.UPDATED_BY, MAX(ca.UPDATED_DATE), ca.CA_REFERENCE_NUMBER,
cl.SOURCE_SYSTEM_CODE, catchment.EST_CATCHMENT_AREA, catchment.SERVICE_PROVIDER_NAME, sds.SDS_NAME, sds.SDS_ADDRESS_TEXT, u.CA_USER_TYPE "USER TYPE",
CASE WHEN ca.REFERRED_IND = 1 THEN 'REFERRED' ELSE 'NOT REFERRED' END REFER_TYPE
FROM CA ca
JOIN(
SELECT TOP 1
CLIENT_ID, MAX(CREATED_DATE) CREATED_DATE
FROM CA
GROUP BY
CLIENT_ID
ORDER BY
MAX(CREATED_DATE)
) maxclient
ON maxclient.CLIENT_ID = ca.CLIENT_ID
AND maxclient.CREATED_DATE = ca.CREATED_DATE
LEFT JOIN CLIENT cl
ON ca.CLIENT_ID = cl.CLIENT_ID
LEFT JOIN (
SELECT * FROM CATCHMENT_AREA catchment LEFT JOIN SERVICE_PROVIDER sp ON sp.SERVICE_PROVIDER_ID = catchment.SERVICE_PROVIDER_ID
) catchment ON ca.CATCHMENT_ID = catchment.CATCHMENT_ID
LEFT JOIN SERVICE_DELIVERY_SITE sds
ON ca.SERVICE_DELIVERY_SITE_ID = sds.SERVICE_DELIVERY_SITE_ID
LEFT JOIN USER u
ON ca.CREATED_BY = u.CA_USER_ID
WHERE (ca.CREATED_DATE) BETWEEN TO_DATE('2021-01-04', 'yyyy-mm-dd') AND TO_DATE('2021-01-08', 'yyyy-mm-dd')
Oracle don't have the top clause:
If you want the max created date from all est_ca_client_id you do:
select est_ca_client_id, max(created_date) created_date
from ca_cdr.est_ca
group by est_ca_client_id
But if you want the last est_ca_client_id from the created_date, assuming you don't have clients created in the same second you can do something like:
select est_ca_client_id
from ca_cdr.est_ca
where created_date = (select max(created_date)
from ca_cdr.est_ca)
I have a small problem with GROUP BY and INNER JOIN. I try to get spent hours in incidents group by user, to see that whitch user are more efficient.
In this moment, I only get the error
'Column 'XXX' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause'
I understand that all of the fields in SELECT statement are necessary in GROUP BY, but if I group for all of this fields, I don't receive that I want.
I think that my problem is because I don't understand GROUP BY and INNER JOIN correctly, so I was trying to learn a lot of websites, but at least in this moment I can't see my error.
Here is my code:
SELECT
id_incident_project AS ID,
i.title AS title,
companyname as social_name,
username as tech_name,
ia.DESCRIPTION_TEXT as description,
CONVERT(varchar, ia.ACTIONDATE, 101) as action_date,
CAST(TIME as INT) as acting_time,
CAST(actions_time as INT) AS total_time
FROM
incident i
INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
WHERE
ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
GROUP BY username
All columns in the SELECT clause that you aren't grouping by must go through an aggregate function. To just get something, you can pass them through MAX:
SELECT
MAX(id_incident_project) AS ID,
MAX(i.title) AS title,
MAX(companyname) as social_name,
username as tech_name,
MAX(ia.DESCRIPTION_TEXT) as description,
MAX(CONVERT(varchar, ia.ACTIONDATE, 101)) as action_date,
MAX(CAST(TIME as INT)) as acting_time,
MAX(CAST(actions_time as INT)) AS total_time
FROM
incident i
INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
WHERE
ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
GROUP BY username
However, when there are multiple rows for the same username after all the joins are completed, this approach will risk values from different source rows being outputted. E.g., if username 'JohnSmith' had (say) two incidents, one on 2019-01-01 with a title of 'Zombie Sighting' and the second on 2019-03-31 with a title of 'Aitch Dropping', then the 'maximum' title pulled out will be 'Zombie Sighting' with a 'maximum' date pulled off of 2019-03-31, so for different incidents.
To avoid this, you can replace the GROUP BY with a partitioning on username instead, order the incidents, and pick out one per username in a consistent fashion:
SELECT
ID, title, social_name, tech_name, description,
action_date, acting_time, total_time
FROM (
SELECT
id_incident_project) AS ID,
i.title AS title,
companyname as social_name,
username as tech_name,
ia.DESCRIPTION_TEXT) as description,
CONVERT(varchar, ia.ACTIONDATE, 101) as action_date,
CAST(TIME as INT) as acting_time,
CAST(actions_time as INT) AS total_time,
ROW_NUMBER () OVER (
PARTITION BY username
ORDER BY
ia.ACTIONDATE DESC, -- pick out latest
i1.ID_INCIDENT DESC -- tie breaker
) AS OrderNum
FROM
incident i
INNER JOIN incident_0001 i1 ON i1.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN incident_action ia ON ia.ID_INCIDENT = i.ID_INCIDENT
INNER JOIN agent a ON a.ID_AGENT = ia.ID_AGENT
INNER JOIN username u on u.ID_USERNAME = a.ID_USERNAME
WHERE
ia.ACTIONDATE BETWEEN '## START DATE (YYYYMMDD)##' AND '## END DATE (YYYYMMDD)##'
) t
WHERE t.OrderNum = 1
I'm querying a table (COURSEPLACE) to generate a result set of students. This contains a range of variables taken from the course table.
I then want to join an Addresses table (which contains multiple address records per student) but only append to the results the 1 postcode that was created on the same (or the closest) date to the date that the Student record was created.
What I've tried is the following, but this only gets me those records where the date value is an exact match - how do I extend this to (effectively) find and select the postcode value from the address record that has the closest date stamp to the student record date stamp?:
SELECT cp.CONTACTNO, cp.AGEONENTRY, cp.COURSETITLE, cp.FACULTY, ad.POSTCODE
FROM COURSEPLACE cp
LEFT OUTER JOIN ADDRESS ad ON ad.CONTACTNO=cp.CONTACTNO
WHERE
cp.TYPE = 'Application'
AND cp.TERM = '2015/6'
AND
(
ad.TYPE = 'Home' AND CONVERT(VARCHAR(23),ad.CREATIONDATE,103) = CONVERT(VARCHAR(23),cp.CREATIONDATE,103)
)
SELECT TOP 1
cp.CONTACTNO, cp.AGEONENTRY, cp.COURSETITLE, cp.FACULTY, ad.POSTCODE,
FROM
COURSEPLACE cp
INNER JOIN ADDRESS ad ON ad.CONTACTNO=cp.CONTACTNO
WHERE CP.TYPE = 'Application'
AND CP.TERM = '2016/5'
AND AD.TYPE = 'Home'
ORDER BY
DATEDIFF(AD.CREATIONDATE, CP.CREATIONDATE) ASC;
Solved it with OUTER APPLY, given as an answer to a previous question:
OUTER APPLY (SELECT TOP 1 * FROM ADDRESS ad2 WHERE ad2.CONTACTNO=cp.CONTACTNO ORDER BY DATEDIFF(dd,cp.CREATIONDATE,ad2.CREATIONDATE)) AD
Give this a whirl....
SELECT cp.CONTACTNO, cp.AGEONENTRY, cp.COURSETITLE, cp.FACULTY, ad.POSTCODE
FROM COURSEPLACE cp
LEFT JOIN ADDRESS ad ON
ad.CONTACTNO=cp.CONTACTNO
INNER JOIN
(SELECT CONTACTNO, MAX(CREATIONDATE) dt
FROM ADDRESS
WHERE CREATIONDATE <= cp.CREATIONDATE
GROUP BY CONTACTNO) ad2 on ad2.dt = ad.CREATIONDATE and ad2.CONTACTNO = ad.CONTACTNO
WHERE
cp.TYPE = 'Application'
AND cp.TERM = '2015/6'
I have tried all possible joins and sub-queries but I cant get the data to only return one value from table 2 that exactly matches the vendor ID. If I dont have the address included in the query, I get one hit for the vendor ID. How can I make it so that when I add the address, I only want the one vendor that I get prior to adding the address.
The vendor from table one must be VEN-CLASS IS NOT NULL.
This was my last attempt using subquery:
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENMAST.VENDOR_CONTCT,
APVENMAST.TAX_ID,
Subquery.ADDR1
FROM (TEST.dbo.APVENMAST APVENMAST
INNER JOIN
(SELECT APVENADDR.ADDR1,
APVENADDR.VENDOR_GROUP,
APVENADDR.VENDOR,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENADDR APVENADDR
INNER JOIN TEST.dbo.APVENMAST APVENMAST
ON (APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP)
AND (APVENADDR.VENDOR = APVENMAST.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)) Subquery
ON (APVENMAST.VENDOR_GROUP = Subquery.VENDOR_GROUP)
AND (APVENMAST.VENDOR = Subquery.VENDOR))
INNER JOIN TEST.dbo.APVENLOC APVENLOC
ON (APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENLOC.VENDOR)
WHERE (APVENMAST.VEN_CLASS IS NOT NULL)
Try this:
SELECT APVENMAST.VENDOR_GROUP
, APVENMAST.VENDOR
, APVENMAST.VENDOR_VNAME
, APVENMAST.VENDOR_CONTCT
, APVENMAST.TAX_ID
, APVENADDR.ADDR1
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN (
select VENDOR_GROUP, VENDOR, ADDR1
, row_number() over (partition by VENDOR_GROUP, VENDOR order by ADDR1) r
from TEST.dbo.APVENADDR
) APVENADDR
ON APVENADDR.VENDOR_GROUP = APVENMAST.VENDOR_GROUP
AND APVENADDR.VENDOR = APVENMAST.VENDOR
AND APVENADDR.r = 1
--do you need this table; you're not using it...
--INNER JOIN TEST.dbo.APVENLOC APVENLOC
--ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
--AND APVENMAST.VENDOR = APVENLOC.VENDOR
WHERE APVENMAST.VEN_CLASS IS NOT NULL
--if the above inner join was to filter results, you can do this instead:
and exists (
select top 1 1
from TEST.dbo.APVENLOC APVENLOC
ON APVENMAST.VENDOR_GROUP = APVENLOC.VENDOR_GROUP
AND APVENMAST.VENDOR = APVENLOC.VENDOR
)
I found another column in the APVENLOC table that I can filter on to get the unique vendor. Turns out if the vendor address is for the main office, the vendor location is set blank.
Easier than I thought it would be!
SELECT DISTINCT APVENMAST.VENDOR_GROUP,
APVENMAST.VENDOR,
APVENMAST.VENDOR_VNAME,
APVENADDR.ADDR1,
APVENMAST.VENDOR_SNAME,
APVENADDR.LOCATION_CODE,
APVENMAST.VEN_CLASS
FROM TEST.dbo.APVENMAST APVENMAST
INNER JOIN TEST.dbo.APVENADDR APVENADDR
ON (APVENMAST.VENDOR_GROUP = APVENADDR.VENDOR_GROUP)
AND (APVENMAST.VENDOR = APVENADDR.VENDOR)
WHERE (APVENADDR.LOCATION_CODE = ' ')
Shaji
I am attempting to write a query that pulls Order information from various tables. I have hit a road block at the target date value.
It seems that every time a target date is changed a new row is added in that table. All I want is to be able to select only the newest Target Date. What should I do?
select Distinct
OR01001 AS OrderNumber,
OR01002 AS OrderType,
OR01003 AS CustomerCode,
OR01015 AS OrderDate,
OR01017 AS CustomerREP,
OR01018 AS ContactPerson,
OR01019 AS SalesmanNumber,
OR03011 - OR03012 AS OpenQuantity,
SC03003 AS StockBalance,
OR01050 AS WarehouseNumber,
OR01072 AS CustomerPO,
OR03005 AS ItemCode,
OR03002 AS LineNumber,
OR500100.OR50004 As TargetDate
from OR010100
INNER Join OR030100 ON OR030100.OR03001 = OR010100.OR01001
INNER Join SL010100 ON SL010100.SL01001 = OR010100.OR01003
INNER Join SC030100 ON SC030100.SC03001 = OR030100.OR03005
Inner JOIN OR500100 ON OR500100.OR50001 = OR010100.OR01001
where OR010100.OR01002 <> 0 AND OR010100.OR01002 <> 6 AND OR01017 = 'SLOTT'
Order by OR01017 ASC;
If I understand your columns correctly, here's one way:
SELECT ...,
OR500100A.OR50004 AS TargetDate
FROM ...
INNER JOIN OR500100 AS OR500100A ON OR500100A.OR50001 = OR010100.OR01001
AND NOT EXISTS(SELECT 1 FROM OR500100 AS OR500100B
WHERE OR500100B.OR5001 = OR010100.OR01001
AND OR500100B.OR50004 > OR500100A.OR50004)
...
This makes sure you only get one OR500100 row with the latest value in OR50004 for the given OR5001.
from what i understand,
SELECT
...
MAX(OR500100.OR50004) As TargetDate
FROM...
WHERE...
GROUP BY --everything but OR500100.OR50004
ORDER BY...
should do the trick
EDIT: ty Ic.