Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2005 Forums
 Transact-SQL (2005)
 Join on

Author  Topic 

JAdauto
Posting Yak Master

160 Posts

Posted - 2009-05-11 : 23:23:18
I have the following data that I need to join and I am just drawing a blank on how to get the data.

Entity
ID LastName FirstName ParentEntityID
1 Jones Jeff 0
2 Stevens Mark 0
3 Jones Cindy 1
4 Stevens Debbie 2

EntityAddress
ID EntityID Address
1 1 jeffjones@yahoo.com
2 1 jjones@businessname.com
3 3 cindyjones@yahoo.com
4 2 markjones@gmail.com

StatementHeader
ID EntityID AmountDue
1 1 25.00
2 2 50.00


What I want is a list of all email addresses that these statements are to go out to. I cannot figure out how to get Cindy's email address included in the results because she doesn't have a StatementHeader record, but she is attached to Jeff because she has his parentEntityID. Does this make sense? I know there must be a way to join this all together, I just cannot get it and get the results I need. Any advice appreciated.

Thx



dineshrajan_it
Posting Yak Master

217 Posts

Posted - 2009-05-12 : 03:13:13
Can u just share how ur output will look like

Iam a slow walker but i never walk back
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-05-12 : 04:31:46
Maybe this:

-- Create tables
DECLARE @Entity TABLE (
[ID] INT
, [LastName] NVARCHAR(255)
, [FirstName] NVARCHAR(255)
, [ParentEntityID] INT
)

DECLARE @EntityAddress TABLE (
[Id] INT
, [entityId] INT
, [address] NVARCHAR(512)
)

DECLARE @StatementHeader TABLE (
[id] INT
, [entityID] INT
, [amountDue] MONEY
)

-- Populate Data
INSERT @entity ([Id], [lastname], [firstname], [parentEntityId])
SELECT 1, 'Jones', 'Jeff', 0
UNION SELECT 2, 'Stevens', 'Mark', 0
UNION SELECT 3, 'Jones', 'Cindy', 1
UNION SELECT 4, 'Stevens', 'Debbie', 2

INSERT @EntityAddress ([Id], [entityId], [address])
SELECT 1, 1, 'jeffjones@yahoo.com'
UNION SELECT 2, 1, 'jjones@businessname.com'
UNION SELECT 3, 3, 'cindyjones@yahoo.com'
UNION SELECT 4, 2, 'markjones@gmail.com'

INSERT @StatementHeader ([Id], [entityID], [amountDue])
SELECT 1, 1, 25.00
UNION SELECT 2, 2, 50.00

-- Select
SELECT
sh.[Id] AS [Statement Id]
, sh.[amountDue] AS [Amount Due]
, e.[firstname] AS [Entity Firstname]
, e.[lastname] AS [Entity Lastname]
, ea.[address] AS [Entity Address]
, ep.[firstname] AS [Parent Firstname]
, ep.[lastname] AS [Parent Lastname]
, eap.[address] AS [Parent Address]
FROM
@statementHeader sh
JOIN @entity e ON e.[ID] = sh.[entityId]
JOIN @entityAddress ea ON ea.[entityId] = e.[ID]

LEFT JOIN @entity ep ON ep.[parentEntityID] = e.[iD]
LEFT JOIN @entityAddress eap ON eap.[entityID] = ep.[Id]

Jeff Jones is going to show up with 2 lines for statement ID 1 (becauses he has 2 different entity address.

You didn't specify if you needed to either pivot or filter based on ome criteria.




Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

Transact Charlie
Master Smack Fu Yak Hacker

3451 Posts

Posted - 2009-05-12 : 05:59:26
Actually -- this is a *lot* harder than it first appears!

This better not be an exam question or similar! -- if it is then the person who set it either doesn't know how hard it is or is a complete bastard!

Assuming that there can be any number of parents and that all parents need to be emailed per order (and only 1 line per order)........

Here is one solution. Never thought I'd ever use this code again....


-- Create tables
DECLARE @Entity TABLE (
[ID] INT
, [LastName] NVARCHAR(255)
, [FirstName] NVARCHAR(255)
, [ParentEntityID] INT
)

DECLARE @EntityAddress TABLE (
[Id] INT
, [entityId] INT
, [address] NVARCHAR(512)
)

DECLARE @StatementHeader TABLE (
[id] INT
, [entityID] INT
, [amountDue] MONEY
)

-- Table to hold the combined addresses for entities
DECLARE @combinedEnts TABLE (
[entityId] INT
, [parentEntityId] INT
, [lastname] NVARCHAR(MAX)
, [firstname] NVARCHAR(MAX)
, [address] NVARCHAR(MAX)
)

-- Populate Data
-- Fred flintstone is a new Parent of Cindy...
-- Therefore his a grandfather of Jeff

INSERT @entity ([Id], [lastname], [firstname], [parentEntityId])
SELECT 1, 'Jones', 'Jeff', 0
UNION SELECT 2, 'Stevens', 'Mark', 0
UNION SELECT 3, 'Jones', 'Cindy', 1
UNION SELECT 4, 'Stevens', 'Debbie', 2
UNION SELECT 5, 'Flintstone', 'Fred', 3

INSERT @EntityAddress ([Id], [entityId], [address])
SELECT 1, 1, 'jeffjones@yahoo.com'
UNION SELECT 2, 1, 'jjones@businessname.com'
UNION SELECT 3, 3, 'cindyjones@yahoo.com'
UNION SELECT 4, 2, 'markjones@gmail.com'
UNION SELECT 5, 5, 'fred@bedrock.com'

INSERT @StatementHeader ([Id], [entityID], [amountDue])
SELECT 1, 1, 25.00
UNION SELECT 2, 2, 50.00

-- Make up a list of combined addresses per entity
INSERT @combinedEnts ([entityID], [parentEntityId], [lastname], [firstname], [address])
SELECT DISTINCT
e.[ID]
, [parentEntityId]
, [lastname]
, [firstname]
, LEFT(d.[address], LEN(d.[address]) - 1) AS [address]
FROM
@entity e
JOIN @EntityAddress ea ON ea.[entityId] = e.[Id]

CROSS APPLY (
SELECT
ea.[address] + '; '
FROM
@entity e2
JOIN @EntityAddress ea ON ea.[entityId] = e.[ID]
WHERE
e.[ID] = e2.[Id]
ORDER BY
ea.[address]
FOR XML PATH('')
)
D ( [address])


-- SELECT statement
;WITH addresses (
[entities]
, [entityID]
, [rootEntityId]
, [names]
, [address]
, [level]
)
AS
(
SELECT
CAST(e.[entityId] AS NVARCHAR(MAX))
, e.[entityId]
, e.[entityId]
, CAST((e.[firstname] + ' ' + e.[lastname]) AS NVARCHAR(MAX))
, CAST(e.[address] AS NVARCHAR(MAX))
, 0
FROM
@combinedEnts e
UNION ALL SELECT
a.[entities] + ', ' + CAST(e.[entityId] AS NVARCHAR(MAX))
, e.[entityId]
, CAST(LEFT(a.[entities], CHARINDEX(a.[entities], ',') + 1) AS INT)
, a.[names] + ', ' + CAST((e.[firstname] + ' ' + e.[lastname]) AS NVARCHAR(MAX))
, a.[address] + '; ' + CAST(e.[address] AS NVARCHAR(MAX))
, [level] + 1
FROM
addresses a
JOIN @combinedEnts e ON e.[parentEntityId] = a.[entityID]
WHERE
', ' + a.[entities] + ', ' NOT LIKE '%, ' + CAST(e.[entityID] AS NVARCHAR(MAX)) + ', %'
)
SELECT
sh.[Id] AS [Statement Header Id]
, sh.[amountDue] AS [Amount Due]
, a.[names] AS [Names]
, a.[address] AS [addresses]
FROM
@statementHeader sh
JOIN (
SELECT
[rootEntityId] AS [reId]
, [names] AS [names]
, [address] AS [address]
, ROW_NUMBER() OVER(PARTITION BY [rootEntityId] ORDER BY [level] DESC) AS [pos]
FROM
addresses
)
a ON
a.[reID] = sh.[entityId]
AND a.[pos] = 1




Charlie
===============================================================
Msg 3903, Level 16, State 1, Line 1736
The ROLLBACK TRANSACTION request has no corresponding BEGIN TRANSACTION
Go to Top of Page

JAdauto
Posting Yak Master

160 Posts

Posted - 2009-05-12 : 09:11:48
quote:
Originally posted by Transact Charlie

Actually -- this is a *lot* harder than it first appears!

This better not be an exam question or similar! -- if it is then the person who set it either doesn't know how hard it is or is a complete bastard!

Assuming that there can be any number of parents and that all parents need to be emailed per order (and only 1 line per order)........




I wish it were an exam question. Unfortunately it is real world stuff. Our clients were able to send their statements to one email address. Because of the demands to go green, many clients have requested to be able to email statements to as many email addresses as they have on file. I do not have a problem with that except that the statement is built for only the main member using his EntityID. So, some clients put their wife's name or secretary's name to also recieve a copy of the statement that is where my problem comes in. I am going to try each of these suggestions this morning and I'll keep you posted. I am not concerned about the order in which the results are produced, but mostly that every email address recieve the correct statement (whether his own or his parent's statement). Thank you so much for your assistance and also making me feel good that this was not a super easy solution that I have the habit of making too difficult.
THX!!!!
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2009-05-12 : 09:13:39
Why not use StatementHeader table in the anchor part of a recursive CTE, and the Entity table in the recursive part?
Then distinct join the CTE to EntityAddress table using FOR XML PATH('') with a semicolon separator instead of a comma displayed here? http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=81254



E 12°55'05.63"
N 56°04'39.26"
Go to Top of Page

JAdauto
Posting Yak Master

160 Posts

Posted - 2009-05-12 : 10:45:03
I do appologize that I did not explain the results I need better. I am only looking for a list of all email addresses and the statementHeaderID.

So in my example For the Jones's family I need the following list.

ID StatementHeaderID EmailAddress Amount
1 1 jeffjones@yahoo.com 25.00
2 1 jjones@business.com 25.00
3 1 cindyjones@yahoo.com 25.00

In one of those examples I got cindy's email address at the end of both of jeff Jones's record, so it doesn't list a 3rd record, just two with another field. In the second example, I took out all the XML code since I dont really need any of that, and just used the part where you are getting a list of all email addresses and I am getting a syntax error, so maybe by removing part of it,it is not working as designed anymore. Thx again for all of your assistance.

Go to Top of Page

JAdauto
Posting Yak Master

160 Posts

Posted - 2009-05-12 : 13:11:38
I finally got it using a union. I'll post my end query here for reference. Note that there are some additional fields here then I posted originally as I was trying to simplify (so ignore). But basically the union worked and now I am getting all the rows I need. I appreciate all of the assistance:

SELECT ea.Address1,
e.LastName,
e.FirstName,
(IsNull(e.Number,'') + IsNull('-' + e.NumberSuffix,'')) as MemberNumber,
ea.ID AS EntityAddressID,
ea.EntityID AS EntityID,
ea.LastEOMEmailDate,
ea.LastEOMEmailARPeriodID,
sh.ID AS StatementHeaderID,
sh.BalanceTypeDesc,
sh.IsSuppressed
FROM EntityAddress ea
INNER JOIN Entity e
on ea.EntityID = e.ID
INNER JOIN CTCReceivables.dbo.StatementHeader sh
on sh.EntityID = e.ID
WHERE ea.AddressTypeID = 2
and ea.UseForFinancial = 1
and sh.StatementMainID = 896

UNION
SELECT
eap.Address1,
ep.LastName,
ep.FirstName,
(IsNull(ep.Number,'') + IsNull('-' + ep.NumberSuffix,'')) as MemberNumber,
eap.ID AS EntityAddressID,
eap.EntityID AS EntityID,
eap.LastEOMEmailDate,
eap.LastEOMEmailARPeriodID,
sh.ID AS StatementHeaderID,
sh.BalanceTypeDesc,
sh.IsSuppressed
FROM EntityAddress eap
INNER JOIN Entity ep
on eap.EntityID = ep.ID
INNER JOIN CTCReceivables.dbo.StatementHeader sh
on sh.EntityID = ep.ParentEntityID
WHERE
eap.AddressTypeID = 2
and eap.useForfinancial = 1
and sh.Statementmainid = 896
and ep.ParentEntityID <> 0
Go to Top of Page
   

- Advertisement -