I've been trying to join a couple tables to get the right result.
The problem is its returning some NULL values where this shouldn't be the case.
EP.ProductId, CreateDate, IsproductActivated and Subject are returning a Null Value.I've noticed it That DossierID and dossier will return a value when I make a right join as stated below.
Could anyone help me with my case?
SELECT
EP.ProductId AS [ProductId]
,MAX(EP.CreateDate) AS [CreateDate]
,EP.IsProductActivated AS [IsProductActivated]
,PC.EntityId AS [DossierID]
,PC.EntityDiscriminator AS [EntityDiscriminator]
,PDCP.Name AS [Subject]
,D.Name AS [Dossier]
FROM
[tblEntityProduct] AS EP
LEFT JOIN .tblPDCProduct AS PDCP
ON PDCP.id = EP.Productid
LEFT JOIN
[tblProductContainerContent] AS PCC
ON PCC.EntityProductId = EP.ProductId
RIGHT JOIN
[tblProductContainer] AS PC
ON PC.Id = PCC.Productcontainerid
LEFT JOIN
[tblDossier] AS D
ON D.Id = PC.Entityid
WHERE PC.EntityId = 2803
GROUP BY EP.Productid
,IsProductActivated
,EntityId
,EntityDiscriminator
,PDCP.name
,D.name
The picture below shows the result of the above query. I want the values it suppose to have instead of the NULL
use inner join to avoid getting null values, because The LEFT JOIN keyword returns all records from the left table (table1), and the matched records from the right table (table2). The result is NULL from the right side, if there is no match. for right join opposite is true of left join
SELECT
EP.ProductId AS [ProductId]
,MAX(EP.CreateDate) AS [CreateDate]
,EP.IsProductActivated AS [IsProductActivated]
,PC.EntityId AS [DossierID]
,PC.EntityDiscriminator AS [EntityDiscriminator]
,PDCP.Name AS [Subject]
,D.Name AS [Dossier]
FROM
[tblEntityProduct] AS EP
JOIN .tblPDCProduct AS PDCP
ON PDCP.id = EP.Productid
JOIN
[tblProductContainerContent] AS PCC
ON PCC.EntityProductId = EP.ProductId
JOIN
[tblProductContainer] AS PC
ON PC.Id = PCC.Productcontainerid
JOIN
[tblDossier] AS D
ON D.Id = PC.Entityid
WHERE PC.EntityId = 2803
GROUP BY EP.Productid
,IsProductActivated
,EntityId
,EntityDiscriminator
,PDCP.name
,D.name
I hate right-joins. They are basically a REQUIRE THIS TABLE regardless of the others leading up to it. Instead, I reversed the query to put the REQUIRED Table in the first position, then LEFT-JOIN to the underlying. Now, based on the structure / join, I would THINK that you start with a product container -- will always exist. Each product container has stuff in it (ProductContainerContent). Then, each content item IS an entity product to get its description. Each container has its own Dossier which may (or not) be assigned at the time the container is being prepared. If I am accurate, most of the LEFT-JOINs should just be standard (inner) JOINs, but lets see what this does against your data.
SELECT
EP.ProductId,
MAX(EP.CreateDate) CreateDate,
EP.IsProductActivated,
PC.EntityId DossierID,
PC.EntityDiscriminator,
PDCP.Name Subject,
D.Name Dossier
FROM
tblProductContainer PC
LEFT JOIN tblProductContainerContent PCC
ON PC.Id = PCC.Productcontainerid
LEFT JOIN tblEntityProduct EP
ON PCC.EntityProductId = EP.ProductId
LEFT JOIN tblPDCProduct PDCP
ON EP.Productid = PDCP.id
LEFT JOIN tblDossier D
ON PC.Entityid = D.Id
WHERE
PC.EntityId = 2803
GROUP BY
EP.Productid,
IsProductActivated,
EntityId,
EntityDiscriminator,
PDCP.name,
D.name
Related
I want to extract a ID , User_ID value from one of the Companies and Contract tables, depending on the ContorollerName value.
select P.TitleProject, P.StartDateProject, P.EndDateProject,P.ControllerID,P.RecordID,P.IsAllocated,P.ProjectStatus_ID,
CN.ControllerName,CN.PersianName,
PU.ProjectID,PU.UserID,PU.RoleID,
CASE
WHEN CN.ControllerName = 'Company' THEN
Companies.Id,Companies.[User_Id]
WHEN CN.ControllerName = 'Contract' THEN
Contracts.Id,Contracts.[User_Id]
END
from Projects P
left outer join Controllers CN ON P.ControllerID = CN.Id
left outer join ProjectUsers PU ON P.Id = PU.ProjectID
where P.IsAllocated = 1
For example, if ContorollerName is 'Company' , the select command is as follows :
select P.TitleProject, P.StartDateProject, P.EndDateProject,P.ControllerID,P.RecordID,P.IsAllocated,P.ProjectStatus_ID,
CN.ControllerName,CN.PersianName,
PU.ProjectID,PU.UserID,PU.RoleID,
Companies.Id,Companies.[User_Id]
You are on the right track -- using left join. But you need to add the tables to the from clause with the appropriate logic.
The logic for the join is quite unclear. The query looks something like this:
select . . .,
coalesce(c.id, co.id) as id,
coalesce(c.user_id, co.user_id) as user_id
from Projects P left join
Controllers CN
on P.ControllerID = CN.Id left join
ProjectUsers PU
on P.Id = PU.ProjectID left join
companies c
on c.? = ? and -- no idea what the right join conditions are
c.ControllerName = 'Company' left join
contracts co
on co.? = ? and -- no idea what the right join conditions are
co.ControllerName = 'Contract'
where P.IsAllocated = 1
In the code below, in the WHERE clause, all the items are checked against that condition "bcp.value = cm.id". Hence if item has no value in bcp table it wont show up, how do i make it show up?
I have tried my best using the likes of sub query without success.
Please help
SELECT DISTINCT
u.firstname,
u.lastname,
u.id,
c.shortname,
c.fullname,
cs.name AS 'Units Code/s Covered',
m.name,
MIN(FROM_UNIXTIME(cmc.timemodified)) AS 'Start Time',
MAX(FROM_UNIXTIME(bgi.dateissued))AS 'Time Completed'
FROM
mdl_course_modules_completion cmc
LEFT JOIN mdl_course_modules cm
ON (cmc.coursemoduleid =cm.id)
LEFT JOIN mdl_course_sections cs
ON (cs.id = cm .section)
LEFT JOIN mdl_modules m
ON (m.id= cm.module )
LEFT JOIN mdl_course c
ON c.id = cm.course AND c.shortname = 'DOM_2015_1'
LEFT JOIN mdl_user u
ON u.id = cmc.userid AND (u.firstname = 'bambo' OR u.firstname = 'Test bambo')
LEFT JOIN mdl_badge_issued bgi
ON bgi.userid = cmc.userid
LEFT JOIN mdl_badge bg
ON bg.id = bgi.badgeid
LEFT JOIN mdl_badge_criteria bc
ON bc.badgeid = bg.id
LEFT JOIN mdl_badge_criteria_param bcp
ON bcp.critid = bc.id AND bcp.value = cm.id
GROUP BY u.firstname, cs.name, FROM_UNIXTIME(bgi.dateissued)
Try this:
AND (bcp.value is null or bcp.value = cm.id)
Just add OR Inside your Where Clause like this
WHERE c.shortname = 'DOM_2015_1' AND (bcp.value = cm.id OR bcp.value IS NULL)
or if it string bcp.value = ""
Update
Before to adding this in Where clause you have to get correct Join maybe it will be better use FULL OUTER JOIN or RIGHT JOIN(Is it possible? It depends on your logic) instead of using LEFT JOIN
WHERE conditions are being applied to entire resultset, thus discarding any of those rows from table mdl_course_modules_completion that don't meet this criteria.
If you only need to check for NULL value that could come from mdl_badge_criteria_param bcp table, then adding additional (or bcp.value is null) would suffice.
This is because your mdl_course_modules cm table is being joined to mdl_badge_criteria_param bcp, and not the main table. If we had the case of joining directly with the main table, making bcp independent from cm, query could sometimes yield wrong results, when cm.id would be holding NULL, and bcp.value was a non-null value.
Keeping that in mind, your solution would be
WHERE c.shortname = 'DOM_2015_1' AND ( bcp.value = cm.id OR bcp.value is null )
Edit You may also consider dropping the entire condition considering bcp.value = cm.id since it seems like you want to allow every record, that has a matching cm.id with the main table to appear and instead applying a cm.id is not null to your where condition.
Can anyone tell me why this sql query is returning this result.
SELECT
M.MatterNumber_Id, M.MatterNumber, M.MatterName,
ISNULL(MP.Role_Cd, 'No Primary') AS PrimaryRole,
ISNULL(E.Name, 'No Primary') AS PrimaryName,
ISNULL(C.CommNumber, 'l.w#abc.ca;m.j#abc.com') AS Email
FROM
Matter M
LEFT OUTER JOIN
MatterPlayer MP ON M.MatterNumber_Id = MP.MatterNumber_Id AND
MP.Role_Cd IN ('Primary Lawyer', 'Primary Staff Member') AND
MP.EndDate IS NULL
LEFT OUTER JOIN
Entity E on MP.Entity_EID = E.Entity_EID
LEFT OUTER JOIN Communication C on MP.Entity_EID = C.Entity_EID AND
C.CommunicationType_Cd = 'Email'
LEFT OUTER JOIN
MatterExposure ME on M.MatterNumber_Id = ME.MatterNumber_Id AND
ME.AssessedDate > '7/10/2014' AND
ME.Currency_CD IS NOT NULL
WHERE
M.MatterStatus_Cd = 'Active' AND
ME.AssessedDate IS NULL AND
M.Matter_Cd in
(SELECT
rpl.Type_CD
FROM
RuleProfile_Tabs rpt
INNER JOIN
RuleProfile_LookupCode rpl ON rpt.RuleProfile_ID = rpl.RuleProfile_ID
WHERE
tab_id = 1034 AND Caption LIKE 'Reportable Matter%')
ORDER BY
Email, M.MatterName
But When i see the results I check one of the records returned and it should not have been returned.
One of the results returned:
Bailey, Richard
In the db i check the values in the tables it should not have been returned because Currency_CD is null and in the sql it states currency_cd is not null. Also the assessed date is AFTER 7/10/2014
Table Values:
MatterStatus_CD:
Active
AssessedDate:
7/24/2014
Currency_CD:
NULL
EndDate:
NULL
Where clauses are used for filtering, not the join clause. Every JOIN should have an ON. Here's a head start.
Select M.MatterNumber_Id, M.MatterNumber, M.MatterName,
IsNull(MP.Role_Cd, 'No Primary') as PrimaryRole,
IsNull(E.Name, 'No Primary') as PrimaryName,
IsNull(C.CommNumber, 'l.w#abc.ca;m.j#abc.com') as Email
From Matter M
Left Outer Join MatterPlayer MP on M.MatterNumber_Id = MP.MatterNumber_Id
Left Outer Join Entity E on MP.Entity_EID = E.Entity_EID
Left Outer Join Communication C on MP.Entity_EID = C.Entity_EID
Left Outer Join MatterExposure ME on M.MatterNumber_Id = ME.MatterNumber_Id
Where M.MatterStatus_Cd = 'Active'
AND ME.AssessedDate is Null
and M.Matter_Cd in (select rpl.Type_CD
from RuleProfile_Tabs rpt
inner join RuleProfile_LookupCode rpl on rpt.RuleProfile_ID = rpl.RuleProfile_ID
where tab_id = 1034 AND Caption like 'Reportable Matter%')
and MP.Role_Cd In ('Primary Lawyer', 'Primary Staff Member')
and MP.EndDate is Null
and ME.AssessedDate > '7/10/2014'
and ME.Currency_CD IS NOT NULL
and C.CommunicationType_Cd = 'Email'
Order by Email, M.MatterName
You are LEFT JOINing MatterExposure onto Matter. Your Me.Currency_CD IS NOT NULL criteria in the LEFT JOIN's ON statement is only saying, "don't join to records where Currency_CD is null..." but because this is a left join, none of your Matter table's records are lost in the join. So when you ask for Currency_CD you will get NULL.
To remove records from your query where Currency_CD is null in the MatterExposure table you will either need to specify Currency_CD IS NOT NULL in your where statement (instead of your join) or will need to use an INNER JOIN to your MatterExposure table.
It is because this join is a LEFT OUTER JOIN. If you want to enforce this join make it an inner join. Or move that check to the WHERE clause.
I'm trying to create a moderately complex query with joins:
SELECT `history`.`id`,
`parts`.`type_id`,
`serialized_parts`.`serial`,
`history_actions`.`action`,
`history`.`date_added`
FROM `history_actions`, `history`
LEFT OUTER JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT OUTER JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
WHERE `history_actions`.`id` = `history`.`action_id`
AND `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
I'd like to replace `parts`.`type_id` in the SELECT statement with `part_list`.`name` where the relationship I need to enforce between the two tables is `part_list`.`id` = `parts`.`type_id`. Also I have to use joins because in some cases `history`.`part_id` may be NULL which obviously isn't a valid part id. How would I modify the query to do this?
Here is some sample date as requested:
history table:
(source: ianburris.com)
serialized_parts table:
(source: ianburris.com)
parts table:
(source: ianburris.com)
part_list table:
(source: ianburris.com)
And what I want to see is:
id name serial action date_added
4 Battery 567 added 2010-05-19 10:42:51
3 Antenna Board 345 added 2010-05-19 10:42:51
2 Main Board 123 added 2010-05-19 10:42:51
1 NULL NULL created 2010-05-19 10:42:51
This would at least be on the right track...
If you're looking to NOT show any parts with an invalid ID, simply change the LEFT JOINs to INNER JOINs (they will restrict NULL values)
SELECT `history`.`id`
, `parts`.`type_id`
, `part_list`.`name`
, `serialized_parts`.`serial`
, `history_actions`.`action`
, `history`.`date_added`
FROM `history_actions`
INNER JOIN `history` ON `history`.`action_id` = `history_actions`.`id`
LEFT JOIN `parts` ON `parts`.`id` = `history`.`part_id`
LEFT JOIN `serialized_parts` ON `serialized_parts`.`parts_id` = `history`.`part_id`
LEFT JOIN `part_list` ON `part_list`.`id` = `parts`.`type_id`
WHERE `history`.`unit_id` = '1'
ORDER BY `history`.`id` DESC
Boy, these backticks make my eyes hurt.
SELECT
h.id,
p.type_id,
pl.name,
sp.serial,
ha.action,
h.date_added
FROM
history h
INNER JOIN history_actions ha ON ha.id = h.action_id
LEFT JOIN parts p ON p.id = h.part_id
LEFT JOIN serialized_parts sp ON sp.parts_id = h.part_id
LEFT JOIN part_list pl ON pl.id = p.type_id
WHERE
h.unit_id = '1'
ORDER BY
history.id DESC
I am trying to take a person and display their current insurance along with their former insurance. I guess one could say that I'm trying to flaten my view of customers or people. I'm running into an issue where I'm getting multiple records back due to multiple records existing within my left join subqueries. I had hoped I could solve this by adding "TOP 1" to the subquery, but that actually returns nothing...
Any ideas?
SELECT
p.person_id AS 'MIRID'
, p.firstname AS 'FIRST'
, p.lastname AS 'LAST'
, pg.name AS 'GROUP'
, e.name AS 'AOR'
, p.leaddate AS 'CONTACT DATE'
, [dbo].[GetPICampaignDisp](p.person_id, '2009') AS 'PI - 2009'
, [dbo].[GetPICampaignDisp](p.person_id, '2008') AS 'PI - 2008'
, [dbo].[GetPICampaignDisp](p.person_id, '2007') AS 'PI - 2007'
, a_disp.name AS 'CURR DISP'
, a_ins.name AS 'CURR INS'
, a_prodtype.name AS 'CURR INS TYPE'
, a_t.date AS 'CURR INS APP DATE'
, a_t.effdate AS 'CURR INS EFF DATE'
, b_disp.name AS 'PREV DISP'
, b_ins.name AS 'PREV INS'
, b_prodtype.name AS 'PREV INS TYPE'
, b_t.date AS 'PREV INS APP DATE'
, b_t.effdate AS 'PREV INS EFF DATE'
, b_t.termdate AS 'PREV INS TERM DATE'
FROM
[person] p
LEFT OUTER JOIN
[employee] e
ON
e.employee_id = p.agentofrecord_id
INNER JOIN
[dbo].[person_physician] pp
ON
p.person_id = pp.person_id
INNER JOIN
[dbo].[physician] ph
ON
ph.physician_id = pp.physician_id
INNER JOIN
[dbo].[clinic] c
ON
c.clinic_id = ph.clinic_id
INNER JOIN
[dbo].[d_Physgroup] pg
ON
pg.d_physgroup_id = c.physgroup_id
LEFT OUTER JOIN
(
SELECT
tr1.*
FROM
[transaction] tr1
LEFT OUTER JOIN
[d_vendor] ins1
ON
ins1.d_vendor_id = tr1.d_vendor_id
LEFT OUTER JOIN
[d_product_type] prodtype1
ON
prodtype1.d_product_type_id = tr1.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] ctype1
ON
ctype1.d_commission_type_id = tr1.d_commission_type_id
WHERE
prodtype1.name <> 'Medicare Part D'
AND tr1.termdate IS NULL
) AS a_t
ON
a_t.person_id = p.person_id
LEFT OUTER JOIN
[d_vendor] a_ins
ON
a_ins.d_vendor_id = a_t.d_vendor_id
LEFT OUTER JOIN
[d_product_type] a_prodtype
ON
a_prodtype.d_product_type_id = a_t.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] a_ctype
ON
a_ctype.d_commission_type_id = a_t.d_commission_type_id
LEFT OUTER JOIN
[d_disposition] a_disp
ON
a_disp.d_disposition_id = a_t.d_disposition_id
LEFT OUTER JOIN
(
SELECT
tr2.*
FROM
[transaction] tr2
LEFT OUTER JOIN
[d_vendor] ins2
ON
ins2.d_vendor_id = tr2.d_vendor_id
LEFT OUTER JOIN
[d_product_type] prodtype2
ON
prodtype2.d_product_type_id = tr2.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] ctype2
ON
ctype2.d_commission_type_id = tr2.d_commission_type_id
WHERE
prodtype2.name <> 'Medicare Part D'
AND tr2.termdate IS NOT NULL
) AS b_t
ON
b_t.person_id = p.person_id
LEFT OUTER JOIN
[d_vendor] b_ins
ON
b_ins.d_vendor_id = b_t.d_vendor_id
LEFT OUTER JOIN
[d_product_type] b_prodtype
ON
b_prodtype.d_product_type_id = b_t.d_product_type_id
LEFT OUTER JOIN
[d_commission_type] b_ctype
ON
b_ctype.d_commission_type_id = b_t.d_commission_type_id
LEFT OUTER JOIN
[d_disposition] b_disp
ON
b_disp.d_disposition_id = b_t.d_disposition_id
WHERE
pg.d_physgroup_id = #PhysGroupID
In Sql server 2005 you can use OUTER APPLY
SELECT p.person_id, s.e.employee_id
FROM person p
OUTER APPLY (SELECT TOP 1 *
FROM Employee
WHERE /*JOINCONDITION*/
ORDER BY /*Something*/ DESC) s
http://technet.microsoft.com/en-us/library/ms175156.aspx
The pattern I normally use for this is:
SELECT whatever
FROM person
LEFT JOIN subtable AS s1
ON s1.personid = person.personid
...
WHERE NOT EXISTS
( SELECT 1 FROM subtable
WHERE personid = person.personid
AND orderbydate > s1.orderbydate
)
Which avoids the TOP 1 clause and maybe makes it a little clearer.
BTW, I like the way you've put this query together in general, except I'd leave out the brackets, assuming you have rationally named tables and columns; and you might even gain some performance (but at least elegance) by listing columns for tr1 and tr2, rather than "tr1.*" and "tr2.*".
Thanks for all of the feedback and ideas...
In the simplest of terms, I have a person table that stores contact information like name, email, etc. I have another table that stores transactions. Each transaction is really an insurance policy that would contain information on the provider, product type, product name, etc.
I want to avoid giving the user duplicate person records since this causes them to look for the duplicates prior to running mail merges, etc. I'm getting duplicates when there is more than 1 transaction that has not been terminated, and when there is more than 1 transaction that has been terminated.
Someone else suggested that I consider a cursor to grab my distinct contact records and then perform the sub selects to get the current and previous insurance information. I don't know if I want to head down that path though.
It's difficult to understand your question so first I'll throw this out there: does changing your SELECT to SELECT DISTINCT do what you want?
Otherwise, let me get this straight, you're trying to get your customers' current insurance and previous insurance, but they may actually have many insurances before that, recorded in the [transactions] table? I looked at your SQL for quite a few minutes but can't figure out what it all means, so could you please reduce it down to only the parts that are necessary? Then I'll think about it some more. It sounds to me like you need a GROUP BY somehow, but I can't work it out exactly yet.
Couldn't take the time to dig through all your SQL (what a beast!), here's an idea that might make things easier to handle:
select
p.person_id, p.name <and other person columns>,
(select <current policy columns>
from pol <and other tables for policy>
where pol.<columns for join> = p.person_id
and <restrictions for current policy>),
(select <previous policy columns>
from pol <and other tables for policy>
where pol.<columns for join> = p.person_id
and <restrictions for previouspolicy>),
<other columns>
from person p <and "directly related" tables>
This makes the statement easier to read by separating the different parts into their own subselects, and it also makes it easier to add a "Top 1" in without affecting the rest of the statement. Hope that helps.