I have what should be a very simple query where I'm trying to get the Part Revision of a Part based on it's max effective date but I keep getting more than 1 result. Would be so great if someone could take a look and tell me what I'm missing? Below is query.
SELECT DISTINCT
Erp.PartRev.PartNum
, Erp.PartMtl.RevisionNum
, Erp.PartRev.EffectiveDate
FROM
Erp.PartRev INNER JOIN
Erp.PartMtl ON Erp.PartRev.Company = Erp.PartMtl.Company
AND Erp.PartRev.PartNum = Erp.PartMtl.PartNum
AND Erp.PartRev.RevisionNum = Erp.PartMtl.RevisionNum
WHERE
(Erp.PartRev.EffectiveDate =
(SELECT MAX(EffectiveDate)
FROM PartRev AS PartRev_1
WHERE (PartRev_1.PartNum = PartMtl.PartNum)
AND (PartRev_1.RevisionNum = PartMtl.RevisionNum)))
GROUP BY
Erp.PartRev.PartNum
, Erp.PartRev.RevisionNum
, Erp.PartMtl.RevisionNum
, Erp.PartRev.EffectiveDate
HAVING (Erp.PartRev.PartNum = N'100-220-2022-01')
and results below:
[enter image description here] (https://i.stack.imgur.com/QVsQn.png)
Expect to see record with most recent date and get 3 records instead of one.
Here is a better example with more than one part and multiple records for each.
SELECT DISTINCT
Erp.PartRev.PartNum
, Erp.PartMtl.RevisionNum
, Erp.PartRev.EffectiveDate
FROM
Erp.PartRev INNER JOIN
Erp.PartMtl ON Erp.PartRev.Company = Erp.PartMtl.Company
AND Erp.PartRev.PartNum = Erp.PartMtl.PartNum
AND Erp.PartRev.RevisionNum = Erp.PartMtl.RevisionNum
WHERE
(Erp.PartRev.EffectiveDate =
(SELECT MAX(EffectiveDate)
FROM PartRev AS PartRev_1
WHERE (PartRev_1.PartNum = PartMtl.PartNum)
AND (PartRev_1.RevisionNum = PartMtl.RevisionNum)))
GROUP BY
Erp.PartRev.PartNum
, Erp.PartRev.RevisionNum
, Erp.PartMtl.RevisionNum
, Erp.PartRev.EffectiveDate
HAVING (Erp.PartRev.PartNum LIKE N'100-220-2022%')
screenshot of results.
(The screenshot looks like SSMS so I'm making the assumption you're using SQL Server)
My guess is you're getting 3 results are because there are 3 companies with the same part number. In that case if you want to ensure one result you'd need to specify for which Company and you can do that without any joins or group by:
SELECT TOP 1
PartNum,
RevisionNum,
EffectiveDate
FROM
Erp.PartRev
WHERE
PartNum = N'100-220-2022-01'
and Comany = '???'
ORDER BY EffectiveDate Desc
Related
I have two tables i am trying to join and do a count on, basically to bring over the date onto the Units table. The problem is that the intakes table has duplicates.
SELECT
Units.Clinic,
Units.display_id,
INTAKES.initial_intake_date,
COUNT(case_note_type_desc) AS CountOfUAs
FROM Units
LEFT JOIN (SELECT display_id,Clinic,initial_intake_date
FROM factIntakesAndDischarges
GROUP BY display_id,Clinic,initial_intake_date ) INTAKES
ON Units.display_id = INTAKES.display_id
AND Units.display_id = INTAKES.Clinic
WHERE casenotes_date BETWEEN '4/9/20' AND '5/9/20'
AND case_note_type_desc = '(UA)'
GROUP BY Units.Clinic,
Units.display_id,
INTAKES.initial_intake_date
ORDER BY CountOfUAs desc,Clinic,display_id,initial_intake_date
This gives me the correct count, but the initial_intake_date comes back NULL. The other join i tried gave me the correct initial_intake_date, but the count was off.
Based on your, I would really expect a query more like this:
SELECT u.Clinic, u.display_id, MIN(i.initial_intake_date) as initial_intake_date,
COUNT(*) AS CountOfUAs
FROM Units u LEFT JOIN
factIntakesAndDischarges fid
ON u.display_id = i.display_id AND
u.display_id = INTAKES.display_id
WHERE u.casenotes_date >= '2020-04-09' AND '2020-05-09' AND
u.case_note_type_desc = '(UA)'
GROUP BY u.Clinic, u.display_id,
ORDER BY CountOfUAs desc, Clinic, display_id, initial_intake_date;
Even if the numbers are not quite right, this is a simpler query for starting to fix.
ON Units.display_id = INTAKES.display_id
AND Units.display_id = INTAKES.Clinic
OR
ON Units.display_id = INTAKES.display_id
AND Units.Clinic = INTAKES.Clinic
WITH UnitsTable AS
(
SELECT
Clinic
, display_id
, CountOfUAs = COUNT(case_note_type_desc)
FROM Units
)
, IntakesTable AS
(
SELECT
display_id
, Clinic
, initial_intake_date
FROM factIntakesAndDischarges
-- I am asuming casenotes_date and casenotes_type_Desc belong to Intakes
-- If not, move this WHERE to UnitsTable above
WHERE
casenotes_date BETWEEN '4/9/20' AND '5/9/20'
AND case_note_type_desc = '(UA)'
GROUP BY
display_id
, Clinic
, initial_intake_date
)
SELECT
U.Clinic
, U.display_id
, I.initial_intake_date
, U.CountOfUAs
FROM UnitsTable U
JOIN IntakesTable I ON I.Display_ID = U.Display_ID
AND I.Clinic = U.Clinic
ORDER BY
U.CountOfUAs desc
, U.Clinic
, U.display_id
, I.initial_intake_date
select DAC.LocationCode, DAC.Description, ReqApp.Rank, App.Approver as UserName,
CASE WHEN app.Approver = app.AlternateApprover THEN ''
ELSE AltApp.AlternateApprover END As AltApprover,
ISNULL(CONVERT(Varchar,AltApp.FromDate,101),'')AS FromDate,
ISNULL(CONVERT(Varchar,AltApp.ToDate,101),'')AS ToDate
from tblAPAlternateApprovers App
INNER JOIN tblAPAlternateApprovers AltApp
ON App.ID = AltApp.ID
INNER JOIN tblAPReqLocations DAC
ON App.tblAPReqLocationsID = DAC.ID
INNER JOIN tblAPReqApprover ReqApp
ON App.Approver = ReqApp.Approver AND
App.tblAPReqLocationsID = ReqApp.LocationID
ORDER BY DAC.LocationCode ASC, ReqApp.Rank asc
Output
When SQL Adds an 'alternate approver' (for purchase orders), it creates an additional record for the actual approver. So, trying to find a way to show only 1 record for those approvers that also have alternates. i.e. 'jlhayes' has 2 records. One with an alternate and one without. For these records, I want to only see the ones that have an alternate.Thank you for your help. I've spend a couple hours and out of ideas.
You can wrap AltApprover case statement in max(AltApprover) and group by DAC.LocationCode, DAC.Description, ReqApp.Rank, App.Approver and do similarly for FromDate and ToDate:
select DAC.LocationCode, DAC.Description, ReqApp.Rank, App.Approver as UserName,
max(CASE WHEN app.Approver = app.AlternateApprover THEN ''
ELSE AltApp.AlternateApprover END) As AltApprover,
max(ISNULL(CONVERT(Varchar,AltApp.FromDate,101),'')) AS FromDate,
max(ISNULL(CONVERT(Varchar,AltApp.ToDate,101),'')) AS ToDate
from tblAPAlternateApprovers App
INNER JOIN tblAPAlternateApprovers AltApp
ON App.ID = AltApp.ID
INNER JOIN tblAPReqLocations DAC
ON App.tblAPReqLocationsID = DAC.ID
INNER JOIN tblAPReqApprover ReqApp
ON App.Approver = ReqApp.Approver AND
App.tblAPReqLocationsID = ReqApp.LocationID
GROUP BY DAC.LocationCode, DAC.Description, ReqApp.Rank, App.Approver
ORDER BY DAC.LocationCode ASC, ReqApp.Rank asc
I have the following query that works fine if I DON'T set a destination table.
SELECT soi.customer_id
, p.department
, p.category
, p.subcategory
, p.tier1
, p.tier2
, pc.bucket as categorization
, SUM(soi.price) as demand
, COUNT(1) as cnt
FROM store.sales_item soi
INNER JOIN datamart.product p ON (soi.product_id = p.product_id)
INNER JOIN daily_customer_fact.dcf_product_categorization pc
ON (p.department = pc.department
AND p.category = pc.category
AND p.subcategory = pc.subcategory
AND p.tier1 = pc.tier1
AND p.tier2 = pc.tier2)
WHERE DATE(soi.created_timestamp) < current_date()
GROUP EACH BY 1,2,3,4,5,6,7 LIMIT 10
However, if I set a destination table, it fails with
Error: Ambiguous field name 'app_version' in JOIN. Please use the table qualifier before field name.
That column exists on the store.sales_item table, but I'm not selecting nor joining to that column.
I've seen this error message before, and it points to the following:
Your query job when specifying a destination table is setting flattenResults to false.
Both of the store.sales_item and datamart.product tables contain a field named "app_version".
If so, I recommend looking at this answer:
https://stackoverflow.com/a/28996481/4001094
As well as this issue report: https://code.google.com/p/google-bigquery/issues/detail?id=459
In your case, you should be able to make your query succeed by doing something like the following, using suggestion #3 from the answer linked above. I'm unable to test it as I don't have access to your source tables, but it should be close to working with flattenResults set to false.
SELECT soi_and_p.customer_id
, soi_and_p.department
, soi_and_p.category
, soi_and_p.subcategory
, soi_and_p.tier1
, soi_and_p.tier2
, pc.bucket as categorization
, SUM(soi_and_p.price) as demand
, COUNT(1) as cnt
FROM
(SELECT soi.customer_id AS customer_id
, p.department AS department
, p.subcategory AS subcategory
, p.tier1 AS tier1
, p.tier2 AS tier2
, soi.price AS price
, soi.created_timestamp AS created_timestamp
FROM store.sales_item soi
INNER JOIN datamart.product p ON (soi.product_id = p.product_id)
) as soi_and_p
INNER JOIN daily_customer_fact.dcf_product_categorization pc
ON (soi_and_p.department = pc.department
AND soi_and_p.category = pc.category
AND soi_and_p.subcategory = pc.subcategory
AND soi_and_p.tier1 = pc.tier1
AND soi_and_p.tier2 = pc.tier2)
WHERE DATE(soi_and_p.created_timestamp) < current_date()
GROUP EACH BY 1,2,3,4,5,6,7 LIMIT 10
I am trying to join 3 reports into one, taking parts out of each report.
This is my script that works with 2 of the reports:
ALTER VIEW [dbo].[v_JB2] AS
SELECT R.*, I.ENTERED, I.PROBLEM_CODE, I.WORKORDER
FROM DALE.DBO.V_JBTRB R
JOIN REPORTS.DBO.V_TC_ANALYSIS_JEREMY I
ON R.HUBID = I.HUB
AND R.NODEID = I.NODE
AND CAST(R.CREATE_DATE AS DATE) = I.ENTERED_DATE
GO
and I want to add this field A.CREATE_DATE-O.ACTUAL_START_DATE AS ASSIGN_SECS from what should be DALE.DBO.V_MTTA
Your join of DALE.DBO.V_MTTA has no ON condition...
Try this:
SELECT R.*, I.ENTERED, I.PROBLEM_CODE, I.WORKORDER,
A.CREATE_DATE-O.ACTUAL_START_DATE as ASSIGN_SECS
FROM
DALE.DBO.V_JBTRB R JOIN
REPORTS.DBO.V_TC_ANALYSIS_JEREMY I
ON R.HUBID = I.HUB AND R.NODEID = I.NODE AND
CAST(R.CREATE_DATE AS DATE) = I.ENTERED_DATE
JOIN DALE.DBO.V_MTTA A ON A.CREATE_DATE-O.ACTUAL_START_DATE = ??? (what do you want this to be joined on? I don't know how your tables are related, but you need a valid ON statement for this join to work)
so the right answer was and i don't think anyone would have been able to tell based on the code was instead of joining a third query i added to my trb query and got the same data not sure why i didn't think of it sooner.
ALTER VIEW [dbo].[v_JBTRB] AS
SELECT SINGLE_USER, RECORD_ID, DIVISION, CREATE_DATETIMEINNEW, OUTAGESTARTDATE, STATUS_DESC, CAST(HUBID AS VARCHAR(255)) AS HUBID, CAST(NODEID AS VARCHAR(255)) AS NODEID, CATEGORY, STATUS, ASSIGN_SECS
FROM OPENQUERY(REMEDY_BI,
'
SELECT
T.RECORD_ID AS Record_ID
, T.DIVISION AS Division
, T.CREATE_DATE_ET AS Create_Date
, T.TIME_IN_NEW AS TimeInNew
, O.ACTUAL_START_DATE_ET AS OutageStartDate
, T.STATUS_DESC
, T.FACILITY AS HubID
, T.NODE AS NodeID
, T.CATEGORY
, T.STATUS
, T.SINGLE_USER
, T.CREATE_DATE-O.ACTUAL_START_DATE AS ASSIGN_SECS
FROM ARNEUSER.VW_BASE_TROUBLE T
JOIN ARNEUSER.VW_BASE_OUTAGE O
ON O.INSTANCE_ID = T.OUTAGE_INSTANCE_ID
AND O.SUBMITTED_BY = T.SUBMITTER
JOIN ARNEUSER.VW_BASE_TROUBLE_TKT_ASGN_HIS A
ON A.TROUBLE_ID = T.TROUBLE_ID
AND A.CREATE_DATE = ( SELECT MIN(CREATE_DATE)
FROM ARNEUSER.VW_BASE_TROUBLE_TKT_ASGN_HIS
WHERE TROUBLE_ID=T.TROUBLE_ID
AND STATUS_NUM=1
AND CREATE_DATE>=O.ACTUAL_START_DATE
AND SUBMITTER=T.SUBMITTER )
WHERE T.STATUS > 3
AND T.REGION = ''Carolina''
AND T.CREATE_DATE >= DATE_TO_UNIX_TZ(TRUNC(SYSDATE)-14)
AND T.CATEGORY IN (''HFC'',''CRITICAL INFRASTRUCTURE'',''VIDEO DIGITAL'',''VIDEO ANALOG'',''DIGITAL PHONE'',''HEADEND/HUB'',''METRO/REGIONAL NETWORK'',''NATIONAL BACKBONE'',''NETWORK'')
')
I added this part the rest was already there if that helps this is one of the reports i was originally joining. I was trying to join another report but it came from the same data base.
, T.CREATE_DATE-O.ACTUAL_START_DATE AS ASSIGN_SECS
AND A.CREATE_DATE = ( SELECT MIN(CREATE_DATE)
FROM ARNEUSER.VW_BASE_TROUBLE_TKT_ASGN_HIS
WHERE TROUBLE_ID=T.TROUBLE_ID
AND STATUS_NUM=1
AND CREATE_DATE>=O.ACTUAL_START_DATE
AND SUBMITTER=T.SUBMITTER )
this is the other query that was being joined for anyone curious the 8 **** replace some sensitive data
ALTER VIEW [dbo].[v_TC_ANALYSIS_JEREMY] AS
SELECT *, cast(entered_date + ' ' + entered_time as datetime) as ENTERED FROM OPENQUERY(ICOMS_H,'
SELECT
W.WONUM AS WORKORDER,
W.WOTYC AS TYPE,
CVGDT2DATE(W.WOEDT) AS ENTERED_DATE,
W.WOQCD AS QUEUE_CODE,
W.WOETM AS TIME_ENTERED,
W.WOPB1 AS PROBLEM_CODE,
TRIM(H.HOAAEQ) AS HUB,
TRIM(H.HONODE) AS NODE,
H.HOZIP5 AS ZIPCODE,
W.WOPOL AS POOL,
P.EXTXD0 AS AREA,
CVGTM2TIME(W.WOETM) AS ENTERED_TIME
FROM
********.WOMHIPF W
JOIN ******.HOSTPF H ON H.HONUM = W.WOHNUM
JOIN CF83PF P ON P.EXPLLL = W.WOPOL
WHERE
W.WOEDT >= REPLACE(CHAR(CURRENT_DATE - 14 DAYS,ISO),''-'','''')-19000000
AND ((WOTYC =''SR'' AND WOQCD IN (''O'',''M'')) OR (WOTYC =''TC''))
AND WOPOL IN (''1'',''2'',''3'',''4'',''6'',''7'',''E'',''M'',''R'')
Ive got an SQL Query trying to get 1 record back when a 1 to many relationship exists.
SELECT dbo.BlogEntries.ID AS blog_entries_id, dbo.BlogEntries.BlogTitle, dbo.BlogEntries.BlogEntry, dbo.BlogEntries.BlogName,
dbo.BlogEntries.DateCreated AS blog_entries_datecreated, dbo.BlogEntries.inActive AS blog_entries_in_active,
dbo.BlogEntries.HtmlMetaDescription AS blog_entries_html_meta_description, dbo.BlogEntries.HtmlMetaKeywords AS blog_entries_html_meta_keywords,
dbo.BlogEntries.image1, dbo.BlogEntries.image2, dbo.BlogEntries.image3, dbo.BlogEntries.formSelector, dbo.BlogEntries.image1Alignment,
dbo.BlogEntries.image2Alignment, dbo.BlogEntries.image3Alignment, dbo.BlogEntries.blogEntryDisplayName, dbo.BlogEntries.published AS blog_entries_published,
dbo.BlogEntries.entered_by, dbo.BlogEntries.dateApproved, dbo.BlogEntries.approved_by, dbo.blog_entry_tracking.id AS blog_entry_tracking_id,
dbo.blog_entry_tracking.blog, dbo.blog_entry_tracking.blog_entry, dbo.BlogCategories.ID, dbo.BlogCategories.BlogCategoryName,
dbo.BlogCategories.BlogCategoryComments, dbo.BlogCategories.DateCreated, dbo.BlogCategories.BlogCategoryTitle, dbo.BlogCategories.BlogCategoryTemplate,
dbo.BlogCategories.inActive, dbo.BlogCategories.HtmlMetaDescription, dbo.BlogCategories.HtmlMetaKeywords, dbo.BlogCategories.entry_sort_order,
dbo.BlogCategories.per_page, dbo.BlogCategories.shorten_page_content, dbo.BlogCategories.BlogCategoryDisplayName, dbo.BlogCategories.published,
dbo.BlogCategories.blogParent
FROM dbo.BlogEntries LEFT OUTER JOIN
dbo.blog_entry_tracking ON dbo.BlogEntries.ID = dbo.blog_entry_tracking.blog_entry LEFT OUTER JOIN
dbo.BlogCategories ON dbo.blog_entry_tracking.blog = dbo.BlogCategories.ID
i have some records assigned to 2 different blogcategories, and when i query everything it returns duplicate records.
How do i only return 1 instance of a blog?
Try this one -
SELECT blog_entries_id = be.Id
, be.BlogTitle
, be.BlogEntry
, be.BlogName
, blog_entries_datecreated = be.DateCreated
, blog_entries_in_active = be.inActive
, blog_entries_html_meta_description = be.HtmlMetaDescription
, blog_entries_html_meta_keywords = be.HtmlMetaKeywords
, be.image1
, be.image2
, be.image3
, be.formSelector
, be.image1Alignment
, be.image2Alignment
, be.image3Alignment
, be.blogEntryDisplayName
, blog_entries_published = be.published
, be.entered_by
, be.dateApproved
, be.approved_by
, blog_entry_tracking_id = bet.Id
, bet.blog
, bet.blog_entry
, bc2.Id
, bc2.BlogCategoryName
, bc2.BlogCategoryComments
, bc2.DateCreated
, bc2.BlogCategoryTitle
, bc2.BlogCategoryTemplate
, bc2.inActive
, bc2.HtmlMetaDescription
, bc2.HtmlMetaKeywords
, bc2.entry_sort_order
, bc2.per_page
, bc2.shorten_page_content
, bc2.BlogCategoryDisplayName
, bc2.published
, bc2.blogParent
FROM dbo.BlogEntries be
LEFT JOIN dbo.blog_entry_tracking bet ON be.Id = bet.blog_entry
OUTER APPLY (
SELECT TOP 1 *
FROM dbo.BlogCategories bc
WHERE bet.blog = bc.Id
) bc2
Also, I would like to mention that in this case, using of aliases in the column names decreases the size of your query and makes it more convenient for understanding.
if you just need one record back, you can use
SELECT TOP 1 dbo.BlogEntries.ID AS blog_entries_id, dbo.Bl.... (same as you have now).
it is more efficient than SELECT DISTINCT
Here is a Northwind Example.
It will return only 1 row in the Order Detail table for each Order.
Use Northwind
GO
Select COUNT(*) from dbo.Orders
select COUNT(*) from dbo.[Order Details]
select * from dbo.Orders ord
join
(select ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY UnitPrice DESC) AS "MyRowID" , * from dbo.[Order Details] innerOD) derived1
on ord.OrderID = derived1.OrderID
Where
derived1.MyRowID = 1
Order by ord.OrderID