JOIN a table with a grouped by table - sql

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

Related

SQL Query with a MAX and Nested Join

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

Join 2 oracle queries

someone, please help to join the below queries.
I have tried my best but not able to join with the condition.
PLN_ID is the common column on both the tables.
Query 1-
SELECT PLN_ID
, ASSORTMENT_GROUP
, STORE
, PLANOGRAM
, STATUS
FROM ACN_PLANOGRAMS
WHERE PLANOGRAM not like '%<Untitled>%'
;
​
Query 2
SELECT distinct(PLN_ID)
, count(*)
, (sum(WIDTH)) AS width
FROM ACN_FIXEL
WHERE type='0'
GROUP BY PLN_ID
HAVING count(*) > 1
;
Please changes join what you want you. Try this query:
SELECT
DISTINCT(a.PLN_ID),
(SUM(a.WIDTH)) AS width,
b.PLN_ID,
b.ASSORTMENT_GROUP,
b.STORE,
b.PLANOGRAM,
b.STATUS
FROM
ACN_FIXEL a
INNER JOIN
ACN_PLANOGRAMS b ON a.PLN_ID = b.PLN_ID
WHERE
a.type = '0'
AND b.PLANOGRAM NOT LIKE '%<Untitled>%'
GROUP BY
a.PLN_ID,
b.PLN_ID,
b.ASSORTMENT_GROUP,
b.STORE,
b.PLANOGRAM,
b.STATUS
HAVING
COUNT(*) > 1
There are several ways to solve this. Without understanding your data model or business logic I offer the simplest solution, a derived table (inline view):
SELECT p.PLN_ID
, p.ASSORTMENT_GROUP
, p.STORE
, p.PLANOGRAM
, p.STATUS
, f.fixel_count
, f.fixel_width
FROM ACN_PLANOGRAMS p
inner join (SELECT PLN_ID
, count(*) as fixel_count
, (sum(WIDTH)) AS fixel_width
FROM ACN_FIXEL
WHERE type='0'
GROUP BY PLN_ID
HAVING count(*) > 1 ) f
on f.pln_id = p.pln_id
WHERE p.PLANOGRAM not like '%<Untitled>%'
;
This solution only returns results for PLN_ID in both result sets. If you have a different logic you may need to use LEFT OUTER JOIN instead.
Make Query 2 a subquery:
SELECT ap.PLN_ID
, ap.ASSORTMENT_GROUP
, ap.STORE
, ap.PLANOGRAM
, ap.STATUS
, sq.cnt
, sq.width
FROM ACN_PLANOGRAMS ap
JOIN (
SELECT PLN_ID
, count(*) AS cnt
, sum(WIDTH) AS width
FROM ACN_FIXEL
WHERE type='0'
GROUP BY PLN_ID
HAVING count(*) > 1
) sq
ON ( sq.PLN_ID = ap.PLN_ID )
WHERE ap.PLANOGRAM not like '%<Untitled>%'
;

The type "geography" is not comparable. It cannot be used in the GROUP BY clause

I have a query like this :
SELECT WorkId,
RegisterDate , Location
FROM (
SELECT dbo.[Work].WorkId ,
dbo.[Work].RegisterDate , dbo.Look.Location
FROM dbo.Municipality INNER JOIN
dbo.[Work] ON dbo.Municipality .Municipality Id = dbo.[Work].MunicipalityWorkId INNER JOIN
dbo.Look ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE (dbo.Look.Location IS NOT NULL) AND Type= 1
) E
GROUP BY WorkId ,RegisterDate , Location
And I get this error :
The type "geography" is not comparable. It cannot be used in the GROUP
BY clause.
I need to add Location to Group By, because I need to display Location in the database. What is the solution for this situation? Thanks.
Here is one way.
Convert the Location to text using Stastext and use it Group by. Then convert it back to geo in Select using STGeomFromText
SELECT WorkId,
RegisterDate,
geography::STGeomFromText(Location.STAsText(), 4326)
FROM (SELECT dbo.[Work].WorkId,
dbo.[Work].RegisterDate,
dbo.Look.Location
FROM dbo.Municipality
INNER JOIN dbo.[Work]
ON dbo.Municipality.MunicipalityId = dbo.[Work].MunicipalityWorkId
INNER JOIN dbo.Look
ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE ( dbo.Look.Location IS NOT NULL )
AND Type = 1) E
GROUP BY WorkId,
RegisterDate,
Location.STAsText()
Referred from this answer
Note : The geography function are CASE sensitive it should be used as it is
STGeomFromText
STAsText
You an not using aggregate function like sum or count so you could avoid group by and order by
SELECT
WorkId
, RegisterDate
, Location
FROM (
SELECT
dbo.[Work].WorkId
, dbo.[Work].RegisterDate
, dbo.Look.Location
FROM dbo.Municipality
INNER JOIN dbo.[Work] ON dbo.Municipality.Municipality Id = dbo.[Work].MunicipalityWorkId
INNER JOIN dbo.Look ON dbo.[Work].LookWorkId = dbo.Look.LookId
WHERE (dbo.Look.Location IS NOT NULL) AND Type= 1
ORDER BY WorkId ,RegisterDate , Location
) E

Joining reports

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'')

SQL Query to get only 1 instance of a record where one to many relationship exists

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