not able to select a column outside left join - sql

I am working with the below query
SELECT * FROM
(SELECT DISTINCT
a.Number
,a.Description
,ISNULL(temp.Quantity,0) Quantity
,LastReceived
,LastIssued
FROM Article a
LEFT JOIN (
select ss.ArticleId
, ss.Quantity
, max(lastreceiveddate) as LastReceived
, max(lastissueddate) as LastIssued
from StockSummary ss
where ss.UnitId = 8
group by ss.ArticleId, ss.StockQuantity
having (MAX(ss.LastReceivedDate) < '2014-09-01' or MAX(ss.LastReceivedDate) is NULL)
AND (MAX(ss.LastIssuedDate) < '2014-09-01' or MAX(ss.LastIssuedDate) is NULL)
) temp on a.Id = temp.ArticleId
WHERE a.UnitId = 8
) main
ORDER BY main.Number
What i want to achieve is to select the articles only with the MAX(ss.LastReceivedDate) and MAX(ss.LastIssuedDate) condition in the Left join query and then do the Quantity Select in the main query.
Note: the quantity column can be 0 or NULL.
Kindly help

Related

Sum count of query when they consist of two or more

Select b.PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', b.PTW_MRC,NULL, null) as Department,count(*) as CountofDept
from U5PERMITAUDIT a inner join R5PERMITTOWORK b on a.PTW_CODE = b.PTW_CODE
Where CREATED between '2016-01-01' and '2021-11-10'
and PTW_MRC = PTW_MRC--isnull(#Dept,PTW_MRC)
and PTW_RESP = PTW_RESP-- isnull(#Auditedby,PTW_RESP)
group by PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', PTW_MRC,NULL, null)
UNION ALL
Select b.PTW_MRC, DBO.r5o7_o7get_desc('EN','MRC', b.PTW_MRC,NULL, null) as Department,count(*) as CountofDept
from U5PERMITAUDIT a inner join R5PERMITTOWORK b on a.PTW_CODE = b.PTW_CODE
Where CREATED between '2016-01-01' and '2021-11-10'
and PTW_MRC = PTW_MRC--isnull(#Dept,PTW_MRC)
and PTW_RESP2 = PTW_RESP2--isnull(#Auditedby,PTW_RESP2)
group by PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', PTW_MRC,NULL, null)
My current Outcome
I want to merge the count of Dept whose departments are same.. Kindly Help!!!
Just wrap your query and do another group by and sum on it.
WITH cte_union AS
(
Select b.PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', b.PTW_MRC,NULL, null) as Department,count(*) as CountofDept
from U5PERMITAUDIT a inner join R5PERMITTOWORK b on a.PTW_CODE = b.PTW_CODE
Where CREATED between '2016-01-01' and '2021-11-10'
and PTW_MRC = PTW_MRC--isnull(#Dept,PTW_MRC)
and PTW_RESP = PTW_RESP-- isnull(#Auditedby,PTW_RESP)
group by PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', PTW_MRC,NULL, null)
UNION ALL
Select b.PTW_MRC, DBO.r5o7_o7get_desc('EN','MRC', b.PTW_MRC,NULL, null) as Department,count(*) as CountofDept
from U5PERMITAUDIT a inner join R5PERMITTOWORK b on a.PTW_CODE = b.PTW_CODE
Where CREATED between '2016-01-01' and '2021-11-10'
and PTW_MRC = PTW_MRC--isnull(#Dept,PTW_MRC)
and PTW_RESP2 = PTW_RESP2--isnull(#Auditedby,PTW_RESP2)
group by PTW_MRC,DBO.r5o7_o7get_desc('EN','MRC', PTW_MRC,NULL, null)
)
SELECT PTW_MRC, Department, SUM(CountofDept)
FROM cte_union
GROUP by PTW_MRC, Department;

Get value from a joined table with no value in primary table

The query shown below is just about right, but I need to have a row for each fiscal Id, i.e. in the output shown below, there needs to be a new row after row 4 with data (screen shot below)
The query I'm using is:
SELECT a.companyId,a.profitCenterID,a.coaID,a.fiscalId,
COALESCE(SUM(a.amount * -1),0) amount,
twelveMo = (
SELECT COALESCE(SUM(amount * -1), 0)
FROM gl a1
LEFT OUTER JOIN fiscal f ON a1.fiscalId=f.Id
WHERE
a1.companyId = a.companyId AND
a1.profitCenterId = a.profitCenterId AND
a1.coaId = a.coaId AND
f.Id > a.fiscalId - 12 AND
f.Id <= a.fiscalId
)
FROM gl a
INNER JOIN coa c ON c.Id=a.coaId AND c.statementType=4
GROUP BY companyId,profitCenterId,coaId,a.fiscalId
ORDER BY companyId,profitCenterId,coaId,a.fiscalId
I don't know your sample datas and your schema's, so I've just added my query on the top of your's.
;WITH CTE_NUM_TEMP AS
(
SELECT 1 AS Fiscal
UNION ALL
SELECT Fiscal+1 FROM CTE_NUM_TEMP
WHERE Fiscal+1<=100
)
SELECT ISNULL(Der.companyId,1) AS companyId,ISNULL(Der.profitCenterID,1) AS profitCenterID,
ISNULL(Der.coaID,40000) AS coaID,IIF(twelveMo IS NULL,LAG(twelveMo,1) OVER(ORDER BY Fiscal),twelveMo) AS twelveMo
FROM CTE_NUM_TEMP AS Num
LEFT JOIN
(
SELECT a.companyId,a.profitCenterID,a.coaID,a.fiscalId,
COALESCE(SUM(a.amount * -1),0) amount,
twelveMo = (
SELECT COALESCE(SUM(amount * -1), 0)
FROM gl a1
LEFT OUTER JOIN fiscal f ON a1.fiscalId=f.Id
WHERE
a1.companyId = a.companyId AND
a1.profitCenterId = a.profitCenterId AND
a1.coaId = a.coaId AND
f.Id > a.fiscalId - 12 AND
f.Id <= a.fiscalId
)
FROM gl a
INNER JOIN coa c ON c.Id=a.coaId AND c.statementType=4
GROUP BY companyId,profitCenterId,coaId,a.fiscalId
)AS Der
ON Num.Fiscal=Der.fiscalId

Count with row_number function SQL CTE

I have the below CTEs that work perfectly, but I want to count the "cl.memb_dim_id" by "cl.post_date" but I am not sure how to do that? When adding in the count function I get an error that highlights the ' row number' so I am assuming I cant have both order and group together ????
WITH
DATES AS
(
select to_date('01-jan-2017') as startdate,to_date('02-jan-2017') as enddate
from dual
),
Claims as (select distinct
cl.memb_dim_id,
row_number () over (partition by cl.Claim_number order by cl.post_date desc) as uniquerow,
cl.Claim_number,
cl.post_date,
ct.claim_type,
ap.claim_status_desc,
dc.company_desc,
dff.io_flag_desc,
pr.product_desc,
cl.prov_dim_id,
cl.prov_type_dim_id
from dw.fact_claim cl
inner join dates d
on 1=1
and cl.post_date >= d.startdate
and cl.post_date <= d.enddate
and cl.provider_par_dim_id in ('2')
and cl.processing_status_dim_id = '1'
and cl.company_dim_id in ('581','585','586','589','590','591','588','592','594','601','602','603','606','596','598','597','579','599','578','577','573','574','576','575')
left join dw.DIM_CLAIM_STATUS ap
on cl.claim_status_dim_id = ap.claim_status_dim_id
left join dw.dim_claim_type ct
on cl.claim_type_dim_id = ct.claim_type_dim_id
and cl.claim_type_dim_id in ('1','2','6','7')
left join dw.DIM_COMPANY dc
on cl.company_dim_id = dc.company_dim_id
left join dw.DIM_IO_FLAG dff
on cl.io_flag_dim_id = dff.io_flag_dim_id
left join dw.dim_product pr
on cl.product_dim_id = pr.product_dim_id
)
Select * from claims where uniquerow ='1'
First, does this work?
count(cl.memb_dim_id) over (partition by cl.Claim_number, cl.post_date) as cnt,
Second, it is strange to be using analytic functions with select distinct.

Join max date from a related table

I have the following queries:
select AccountId
into #liveCustomers
from AccountExtensionBase where New_duos_group not in ('T053','T054')
and New_AccountStage = 7
select AccountId
into #customerWhoLeft
from New_marketmessagein as a
inner join AccountExtensionBase as b on a.new_accountmminid = b.AccountId
where New_MessageTypeCode = '105L'
and a.New_EffectiveFromDate > '30 jun 2016'
and b.New_duos_group not in ('T053','T054')
select
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
into
#monthCustomers
from
AccountExtensionBase
where
AccountId in (select * from #customerWhoLeft)
or
AccountId in (select * from #liveCustomers)
I now wish to join a table called usagefactorExtensionBase and join only the row containing the most recent read date but when I try to join this to my table of 4985 monthly customers I get like 106,813 rows using this code so I think my join or methodology has gone awry, can someone please help me correct the error so I display the list of monthCustomers plus the read details of their most recent read.
Attempting:
select
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
, max(b.New_EffectiveFromDate)
, b.New_ActualUsageFactor
, b.New_EstimatedUseage
from
#monthCustomers as a
left join
New_marketmessageinusagefactorExtensionBase as b
on a.AccountId = b.new_accountmmusagefactorid
group by
accountid
, New_MPRNNumber
, New_duos_group
, New_CommercialAgreementDayRate
, New_CommercialAgreementNightRate
, New_CommercialAgreementHeatRate
, New_Tariffpriceagreedatsignup
, New_Tariffname
, b.New_ActualUsageFactor
, b.New_EstimatedUseage
try this,
SELECT
accountid,
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
b.New_EffectiveFromDate,
b.New_ActualUsageFactor,
b.New_EstimatedUseage
FROM #monthCustomers AS a
-- Get only max date rows for each AccountID
LEFT JOIN( SELECT t1.*
FROM New_marketmessageinusagefactorExtensionBase AS t1
INNER JOIN ( SELECT new_accountmmusagefactorid, MAX(New_EffectiveFromDate) AS New_EffectiveFromDate_Max
FROM New_marketmessageinusagefactorExtensionBase
GROUP BY new_accountmmusagefactorid
) AS t2 ON t2.new_accountmmusagefactorid = t1.new_accountmmusagefactorid
AND t2.New_EffectiveFromDate_Max = t1.New_EffectiveFromDate
)AS b
ON a.AccountId = b.new_accountmmusagefactorid
there might be rows with same date, try below if is works,
SELECT
accountid,
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
b.New_EffectiveFromDate,
b.New_ActualUsageFactor,
b.New_EstimatedUseage
FROM #monthCustomers AS a
-- Get only max date rows for each AccountID
LEFT JOIN( SELECT New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
MAX(New_EffectiveFromDate) AS New_EffectiveFromDate,
New_ActualUsageFactor,
New_EstimatedUseage
FROM New_marketmessageinusagefactorExtensionBase AS t1
GROUP BY
New_MPRNNumber,
New_duos_group,
New_CommercialAgreementDayRate,
New_CommercialAgreementNightRate,
New_CommercialAgreementHeatRate,
New_Tariffpriceagreedatsignup,
New_Tariffname,
New_ActualUsageFactor,
New_EstimatedUseage
)AS b
ON a.AccountId = b.new_accountmmusagefactorid

Inner join that ignore singlets

I have to do an self join on a table. I am trying to return a list of several columns to see how many of each type of drug test was performed on same day (MM/DD/YYYY) in which there were at least two tests done and at least one of which resulted in a result code of 'UN'.
I am joining other tables to get the information as below. The problem is I do not quite understand how to exclude someone who has a single result row in which they did have a 'UN' result on a day but did not have any other tests that day.
Query Results (Columns)
County, DrugTestID, ID, Name, CollectionDate, DrugTestType, Results, Count(DrugTestType)
I have several rows for ID 12345 which are correct. But ID 12346 is a single row of which is showing they had a row result of count (1). They had a result of 'UN' on this day but they did not have any other tests that day. I want to exclude this.
I tried the following query
select
c.desc as 'County',
dt.pid as 'PID',
dt.id as 'DrugTestID',
p.id as 'ID',
bio.FullName as 'Participant',
CONVERT(varchar, dt.CollectionDate, 101) as 'CollectionDate',
dtt.desc as 'Drug Test Type',
dt.result as Result,
COUNT(dt.dru_drug_test_type) as 'Count Of Test Type'
from
dbo.Test as dt with (nolock)
join dbo.History as h on dt.pid = h.id
join dbo.Participant as p on h.pid = p.id
join BioData as bio on bio.id = p.id
join County as c with (nolock) on p.CountyCode = c.code
join DrugTestType as dtt with (nolock) on dt.DrugTestType = dtt.code
inner join
(
select distinct
dt2.pid,
CONVERT(varchar, dt2.CollectionDate, 101) as 'CollectionDate'
from
dbo.DrugTest as dt2 with (nolock)
join dbo.History as h2 on dt2.pid = h2.id
join dbo.Participant as p2 on h2.pid = p2.id
where
dt2.result = 'UN'
and dt2.CollectionDate between '11-01-2011' and '10-31-2012'
and p2.DrugCourtType = 'AD'
) as derived
on dt.pid = derived.pid
and convert(varchar, dt.CollectionDate, 101) = convert(varchar, derived.CollectionDate, 101)
group by
c.desc, dt.pid, p.id, dt.id, bio.fullname, dt.CollectionDate, dtt.desc, dt.result
order by
c.desc ASC, Participant ASC, dt.CollectionDate ASC
This is a little complicated because the your query has a separate row for each test. You need to use window/analytic functions to get the information you want. These allow you to do calculate aggregation functions, but to put the values on each line.
The following query starts with your query. It then calculates the number of UN results on each date for each participant and the total number of tests. It applies the appropriate filter to get what you want:
with base as (<your query here>)
select b.*
from (select b.*,
sum(isUN) over (partition by Participant, CollectionDate) as NumUNs,
count(*) over (partition by Partitipant, CollectionDate) as NumTests
from (select b.*,
(case when result = 'UN' then 1 else 0 end) as IsUN
from base
) b
) b
where NumUNs <> 1 or NumTests <> 1
Without the with clause or window functions, you can create a particularly ugly query to do the same thing:
select b.*
from (<your query>) b join
(select Participant, CollectionDate, count(*) as NumTests,
sum(case when result = 'UN' then 1 else 0 end) as NumUNs
from (<your query>) b
group by Participant, CollectionDate
) bsum
on b.Participant = bsum.Participant and
b.CollectionDate = bsum.CollectionDate
where NumUNs <> 1 or NumTests <> 1
If I understand the problem, the basic pattern for this sort of query is simply to include negating or exclusionary conditions in your join. I.E., self-join where columnA matches, but columns B and C do not:
select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
and t1.PkId != t2.PkId
and t1.category != t2.category
)
Put the conditions in the WHERE clause if it benchmarks better:
select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
)
where
t1.PkId != t2.PkId
and t1.category != t2.category
And it's often easiest to start with the self-join, treating it as a "base table" on which to join all related information:
select
[columns]
from
(select
[columns]
from
table t1
join table t2 on (
t1.NonPkId = t2.NonPkId
)
where
t1.PkId != t2.PkId
and t1.category != t2.category
) bt
join [othertable] on (<whatever>)
join [othertable] on (<whatever>)
join [othertable] on (<whatever>)
This can allow you to focus on getting that self-join right, without interference from other tables.