SubQuery inner join with condition - sql

I have two tables (REPORTDETAILS, REPORTITEMS), I want to query one of them to find a max value + 1 between two values, but I also want to find the max value + 1 of another table at the same time.
I am getting the correct value from the first table, but the second value is incorrect because of the condition that I have built in for the first table.
What is the correct way to right this statement?
Thanks for your help as always.
Here is my statement.
SELECT MAX(rd.REPNUMBER) + 1 as REPNUMBER,
MAX(ri.REPITEM) + 1 as REPITEM
FROM REPORTDETAILS rd INNER JOIN REPORTITEMS ri ON rd.REPNUMBER = ri.REPNUMBER
WHERE rd.REPNUMBER BETWEEN 11000000 and 11099999;

You could use CASE within your MAX statement and remove your WHERE criteria:
SELECT MAX(CASE WHEN rd.REPNUMBER BETWEEN 11000000 and 11099999
THEN rd.REPNUMBER END) + 1 as REPNUMBER,
MAX(ri.REPITEM) + 1 as REPITEM
FROM REPORTDETAILS rd
INNER JOIN REPORTITEMS ri ON rd.REPNUMBER = ri.REPNUMBER
Because of the INNER JOIN, this would still only show the max(repitem) based on the matching records between reportdetails and reportitems. If you just want the max(repitem) regardless of the reportdetails, then you could use a CROSS JOIN instead.

Related

SQL Query SELECT same data from different tables, show all records, but show / display matches

I have two tables where I would like to compare information (In order to get from the initial table to the other I need to go through a reference table).
I am getting the results I am looking for except when a match is found an extra row of data is added (screen shot below). There should be only 4 rows, I don't understand why the value in column 1 row 5 wasn't just added to column 1 row 4.
Any help would be much appreciated.
Code
Select DISTINCT
CASE
WHEN LIC.ORDER_NUM = LN_STLIC.ORDER_NUMBER THEN LIC.ORDER_NUM
ELSE ''
END 'ORDER Number 1',
LN_STLIC.ORDER_NUMBER 'ORDER Number 2'
from LN_TABLE1 LN_STLIC
LEFT OUTER JOIN LN_REF LN_PDE_RTN on LN_STLIC.LNPID = LN_PDE_RTN.LNPID
LEFT OUTER JOIN LN_TABLE2 LIC on LN_PDE_RTN.ID = LIC.ID
where LIC.ID = '123456'
Example Table Data
LN_TABLE1
LN_REF
LN_TABLE2
Results
You've defined Order Number 1 as
CASE
WHEN LIC.ORDER_NUM = LN_STLIC.ORDER_NUMBER THEN LIC.ORDER_NUM
ELSE ''
END
So, you can reasonably infer that when Order Number 1 is blank, it's because LIC.ORDER_NUM doesn't match LN_STLIC.ORDER_NUMBER.
You asked for a DISTINCT on the combination of Order Number 1 and Order Number 2. So every combination of the two of them that appears in the data, will appear just once.
Because LN_TABLE1 has four different order numbers for the same value of LNPID, you're going to generate 3 records with a blank Order Number 1 and Order Number 2 set to 210414. But the distinct will take it down to just one, plus the one where they match (records 4 and 5 in your example).
You'd probably have to join on LIC.ORDER_NUM = LN_STLIC.ORDER_NUMBER in order to match the order numbers to each other, and get only 1 record for order number 210414.
I could give you a better query if I knew a bit more about what you were trying to achieve.
Your question is confusing:
We can do a simple LEFT JOIN with LN_STLIC and LIC :
Select CASE WHEN LN_STLIC.order_number = LIC.order_num THEN LIC.ORDER_NUM END ORD
Number1, LN_STLIC.order_number ORD Number2
from LN_TABLE1 LN_STLIC
LEFT OUTER JOIN LN_TABLE2 LIC ON LN_STLIC.order_number = LIC.order_num;
Also doing the below also gets you the same things in case you want to use LIC.ID = '1234' and there is no need to use DISTINCT.
Select
CASE WHEN LIC.ORDER_NUM = LN_STLIC.ORDER_NUMBER THEN LIC.ORDER_NUM
ELSE ''
END ORD_NBR_1,
LN_STLIC.ORDER_NUMBER ORD_NBR_2
from #LN_TABLE1 LN_STLIC
LEFT OUTER JOIN #LN_REF LN_PDE_RTN on LN_STLIC.LNPID = LN_PDE_RTN.LNPID
LEFT OUTER JOIN #LN_TABLE2 LIC on LN_PDE_RTN.ID = LIC.ID AND
LN_STLIC.ORDER_NUMBER =LIC.ORDER_NUM
;

SQL Join / Union

I have two statements that I want to merge into one output.
Statement One:
select name from auxiliary_variable_inquiry
where inquiry_idbr_code = '063'
Returns the following list of names:
Name
------------
Affiliates
NetBookValue
Parents
Worldbase
Statement Two:
select name, value from auxiliary_variable_value
where inquiry_idbr_code = '063'
and ru_ref = 20120000008
and period = 200912
Returns the following:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
I would like to have an output like this:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
Parents 0
Worldbase 0
So basically, if the second query only returns 2 names and values, I'd still like to display the complete set of names from the first query, with no values. If all four values were returned by both queries, then all four would be displayed.
Sorry I must add, im using Ingres SQL so im unable to use the ISNULL function.
You can do a left join. This ensures that all records from the first table will stay included. Where value is null, no child record was found, and we use coalesce to display 0 in these cases.
select i.name, COALESCE(v.Value,0) from auxiliary_variable_inquiry i
left join auxiliary_variable_value v
on v.inquiry_idbr_code = i.inquiry_idbr_code
and v.ru_ref = 20120000008
and v.period = 200912
where i.inquiry_idbr_code = '063'
I'd recommend a self-JOIN using the LEFT OUTER JOIN syntax. Include your 'extra' conditions from the second query in the JOIN condition, while the first conditions stay in the WHERE, like this:
select a.name, CASE WHEN b.Value IS NULL THEN 0 ELSE b.Value END AS Value
from
auxiliary_variable_inquiry a
LEFT JOIN
auxiliary_variable_inquiry b ON
a.name = b.name and -- replace this with your real ID-based JOIN
a.inquiry_idbr_code = b.inquiry_idbr_code AND
b.ru_ref = 20120000008 AND
b.period = 200912
where a.inquiry_idbr_code = '063'
if i got right, you should use something like:
SELECT i.NAME,
v.NAME,
v.value
FROM auxiliary_variable_inquiry i
LEFT JOIN auxiliary_variable_value v
ON i.inquiry_idbr_code = v.inquiry_idbr_code
WHERE v.ru_ref = 20120000008
AND v.period = 200912

SQL: Want to alter the conditions on a join depending on values in table

I have a table called Member_Id which has a column in it called Member_ID_Type. The select statement below returns the value of another column, id_value from the same table. The join on the tables in the select statement is on the universal id column. There may be several entries in that table with this same universal id.
I want to adjust the select statement so that it will return the id_values for entries that have member_id_type equal to '7'. However if this is null then I want to return records that have member_id_type equal to '1'
So previously I had a condition on the join (commented out below) but that just returned records that had member_id_type equal to '7' and otherwise returned null.
I think I may have to use a case statement here but I'm not 100% sure how to use it in this scenario
SELECT TOP 1 cm.Contact_Relation_Gid,
mc.Universal_ID,
mi.ID_Value,
cm.First_Name,
cm.Last_Name,
cm.Middle_Name,
cm.Name_Suffix,
cm.Email_Address,
cm.Disability_Type_PKID,
cm.Race_Type_PKID,
cm.Citizenship_Type_PKID,
cm.Marital_Status_Type_PKID,
cm.Actual_SSN,
cm.Birth_Date,
cm.Gender,
mc.Person_Code,
mc.Relationship_Code,
mc.Member_Coverage_PKID,
sc.Subscriber_Coverage_PKID,
FROM Contact_Member cm (NOLOCK)
INNER JOIN Member_Coverage mc (NOLOCK)
ON cm.contact_relation_gid = mc.contact_relation_gid
AND mc.Record_Status = 'A'
INNER JOIN Subscriber_Coverage sc (NOLOCK)
ON mc.Subscriber_Coverage_PKID = sc.Subscriber_Coverage_PKID
AND mc.Record_Status = 'A'
LEFT outer JOIN Member_ID mi ON mi.Universal_ID = cm.Contact_Gid
--AND mi.Member_ID_Type_PKID='7'
WHERE cm.Contact_Relation_Gid = #Contact_Relation_Gid
AND cm.Record_Status = 'A'
Join them both, and use one if the other is not present:
select bt.name
, coalesce(eav1.value, eav2.value) as Value1OrValue2
from BaseTable bt
left join EavTable eav1
on eav1.id = bt.id
and eav1.type = 1
left join EavTable eav2
on eav2.id = bt.id
and eav2.type = 2
This query assumes that there is never more than one record with the same ID and Type.

Join Table on one record but calculate field based on other rows in the join

I am trying to write a query to Identify my subscribers who have abandoned a shopping cart in the last day but also I need a calculated field that represents weather or not they have received and incentive in the last 7 days.
I have the following tables
AbandonCart_Subscribers
Sendlog
The first part of the query is easy, get abandoners in the last day
select a.* from AbandonCart_Subscribers
where DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Here is my attempt to calculate the incentive but I am fairly certain it is not correct as IncentiveRecieved is always 0 even when I know it should not be...
select a.*,
CASE
WHEN DATEDIFF(D,s.SENDDATE,GETDATE()) >= 7
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Here is a SQL fiddle with the objects and some data. I would really appreciate some help.
Thanks
http://sqlfiddle.com/#!3/f481f/1
Kishore is right in saying the main problem is that it should be <=7, not >=7. However, there is another problem.
As it stands, you could get multiple results. You don't want to do a left join on SendLog in case the same email address is in there more than once. Instead you should be getting a unique result from that table. There's a couple of ways of doing that; here is one such way which uses a derived table. The table I have called s will give you a unique list of emails that have been sent an incentive in the last week.
select a.*,
CASE
WHEN s.EmailAddress is not null
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join (select distinct EmailAddress
from SendLog s
where s.CampaignID IS NULL
and DATEDIFF(D,s.SENDDATE,GETDATE()) <= 7
) s on a.EmailAddress = s.EmailAddress
where DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
You can set a variable using a condition:
select a.*,(DATEDIFF(D,s.SENDDATE,GETDATE()) >= 7) as `IncentiveRecieved `
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Is this what you're looking for?
should it not be less than 7 instead of greater than 7?
select a.*,
CASE
WHEN DATEDIFF(D,s.SENDDATE,GETDATE()) <= 7 AND CampaignID is not null
THEN 1
ELSE 0
END As IncentiveRecieved
from AbandonCart_Subscribers a
left join SendLog s on a.EmailAddress = s.EmailAddress --and s.CampaignID IS NULL
where
DATEDIFF(day,a.DateAbandoned,GETDATE()) <= 1
Hope this satisfies your need.

Why left join is not giving distinct result?

I have following sql query and my left join is not giving me distinct result please help me to trace out.
SELECT DISTINCT
Position.Date,
Position.SecurityId,
Position.PurchaseLotId,
Position.InPosition,
ISNULL(ClosingPrice.Bid, Position.Mark) AS Mark
FROM
Fireball_Reporting.dbo.Reporting_DailyNAV_Pricing POSITION WITH (NOLOCK, READUNCOMMITTED)
LEFT JOIN Fireball.dbo.AdditionalSecurityPrice ClosingPrice WITH (NOLOCK, READUNCOMMITTED) ON
ClosingPrice.SecurityID = Position.PricingSecurityID AND
ClosingPrice.Date = Position.Date AND
ClosingPrice.SecurityPriceSourceID = #SourceID AND
ClosingPrice.PortfolioID IN (5,6)
WHERE
DatePurchased > #NewPositionDate AND
Position.Date = #CurrentPositionDate AND
InPosition = 1 AND
Position.PortfolioId IN (
SELECT
PARAM
FROM
Fireball_Reporting.dbo.ParseMultiValuedParameter(#PortfolioId, ',')
) AND
(
Position > 1 OR
Position < - 1
)
Now here in above my when I use LEFT JOIN ISNULL(ClosingPrice.Bid, Position.Mark) AS Mark and LEFT JOIN it is giving me more no of records with mutiple portfolio ids
for e.g . (5,6)
If i put portfolioID =5 giving result as 120 records
If i put portfolioID =6 giving result as 20 records
When I put portfolioID = (5,6) it should give me 140 records
but it is giving result as 350 records which is wrong . :(
It is happening because when I use LEFT JOIN there is no condition of PurchaseLotID in that as table Fireball.dbo.AdditionalSecurityPrice ClosingPrice not having column PurchaseLotID so it is giving me other records also whoes having same purchaseLotID's with diferent prices .
But I dont want that records
How can I eliminate those records ?
You get one Entry per DailyLoanAndCashPosition.PurchaseLotId = NAVImpact.PurchaseLotId
which would mean you must have more entrys in with the same PurchaseLotId
The most likely cause is that the left join produces duplicated PurchaseLotIds. The best way to know if if you perform a select distinct(PurchaseLotId) on your left side of the inner join.