January 23, 2010 at 8:36 pm
I have two Tables, A -- has a bunch of data I retrieve with the relevant (to this problem) field being FCode -- char(10)
FCode can have nothing ('') or 1-3 failure codes made up of Fxx where x = number.
There is a related table B that has
FCode - char(3)
FCodeDescription - char(50)
What I need is when I query Table A I need to have the FCodeDescription (if applicable) returned inline withe the other data, the issue I'm hving is how to get the description back when there is more than one FCode. i.e. FCode in Table A = 'F02F05'.
Any help is appreciated.
January 23, 2010 at 11:58 pm
You need to write a function which turns the multi valued char(10) column into multi rowed table.
Then you can join that table to TableB and get the values needed.
I assume that you always send one column from TableA
Cheers,
Prithiviraj Kulasingham
http://preethiviraj.blogspot.com/
January 24, 2010 at 3:04 am
Since the multi valued column is char(10), there can be a maximum of three values (btw: I'd rather use a char(9) length...).
Instead of calling the function I'd probably do it inside the query.
However, having a split string function available will help a lot if there are more columns holding multiple values (e.g. comma separated lists).
DECLARE @t TABLE (id INT, code CHAR(10))
INSERT INTO @t
SELECT 1,'F02F05F03' UNION ALL
SELECT 2,'F05F03' UNION ALL
SELECT 3,'F02F05' UNION ALL
SELECT 4,'F02'
SELECT
id,
SUBSTRING(code,3*n+1, 3) AS code
FROM @t
CROSS APPLY
(
SELECT 0 AS n UNION ALL
SELECT 1 UNION ALL
SELECT 2
) b
WHERE n < LEN(code)/3
/* result set:
idcode
1F02
1F05
1F03
2F05
2F03
3F02
3F05
4F02
*/
January 24, 2010 at 3:31 am
Here's a completely different way which returns the codes in the same row.
CREATE TABLE #A (id INT, FCode CHAR(10))
INSERT INTO #A
SELECT 1,'F02F05F03' UNION ALL
SELECT 2,'F05F03' UNION ALL
SELECT 3,'F02F05' UNION ALL
SELECT 4,'F02'
CREATE TABLE #B (FCode CHAR(3), FCodeDescription VARCHAR(20))
INSERT INTO #B (FCode, FCodeDescription)
SELECT 'F02', 'F02 description' UNION ALL
SELECT 'F03', 'F03 description' UNION ALL
SELECT 'F04', 'F04 description' UNION ALL
SELECT 'F05', 'F05 description' UNION ALL
SELECT 'F06', 'F06 description'
SELECT a.*,
'#' AS '#',
b1.FCodeDescription AS Desc1,
b2.FCodeDescription AS Desc2,
b3.FCodeDescription AS Desc3
FROM #A a
LEFT JOIN #B b1 ON b1.FCode = SUBSTRING(a.FCode, 1, 3)
LEFT JOIN #B b2 ON b2.FCode = SUBSTRING(a.FCode, 4, 3)
LEFT JOIN #B b3 ON b3.FCode = SUBSTRING(a.FCode, 7, 3)
Results:
id FCode # Desc1 Desc2 Desc3
----------- ---------- ---- -------------------- -------------------- --------------------
1 F02F05F03 # F02 description F05 description F03 description
2 F05F03 # F05 description F03 description NULL
3 F02F05 # F02 description F05 description NULL
4 F02 # F02 description NULL NULL
For better assistance in answering your questions, please read this[/url].
Hidden RBAR: Triangular Joins[/url] / The "Numbers" or "Tally" Table: What it is and how it replaces a loop[/url] Jeff Moden[/url]
January 24, 2010 at 4:08 am
There's yet another way to do this if you want an output row for each code - with OR in the join to the lookup. This isn't often recommended because the performance can be poor, so adding in this join as a last step after any preaggregation of the main query would be the way to go, something like this:
SELECT a.*, b1.FCodeDescription
FROM (SELECT id, FCode FROM #A WHERE 1 = 1) a
LEFT JOIN #B b1
ON b1.FCode = SUBSTRING(a.FCode, 1, 3)
OR b1.FCode = SUBSTRING(a.FCode, 4, 3)
OR b1.FCode = SUBSTRING(a.FCode, 7, 3)
ORDER BY a.id
Cheers
ChrisM@home
For better assistance in answering your questions, please read this[/url].
Hidden RBAR: Triangular Joins[/url] / The "Numbers" or "Tally" Table: What it is and how it replaces a loop[/url] Jeff Moden[/url]
January 24, 2010 at 5:19 pm
This works perfectly for what I have to do.
Thank you so much.
January 24, 2010 at 5:28 pm
lobbymuncher (1/24/2010)
Here's a completely different way which returns the codes in the same row.
CREATE TABLE #A (id INT, FCode CHAR(10))
INSERT INTO #A
SELECT 1,'F02F05F03' UNION ALL
SELECT 2,'F05F03' UNION ALL
SELECT 3,'F02F05' UNION ALL
SELECT 4,'F02'
CREATE TABLE #B (FCode CHAR(3), FCodeDescription VARCHAR(20))
INSERT INTO #B (FCode, FCodeDescription)
SELECT 'F02', 'F02 description' UNION ALL
SELECT 'F03', 'F03 description' UNION ALL
SELECT 'F04', 'F04 description' UNION ALL
SELECT 'F05', 'F05 description' UNION ALL
SELECT 'F06', 'F06 description'
SELECT a.*,
'#' AS '#',
b1.FCodeDescription AS Desc1,
b2.FCodeDescription AS Desc2,
b3.FCodeDescription AS Desc3
FROM #A a
LEFT JOIN #B b1 ON b1.FCode = SUBSTRING(a.FCode, 1, 3)
LEFT JOIN #B b2 ON b2.FCode = SUBSTRING(a.FCode, 4, 3)
LEFT JOIN #B b3 ON b3.FCode = SUBSTRING(a.FCode, 7, 3)
Results:
id FCode # Desc1 Desc2 Desc3
----------- ---------- ---- -------------------- -------------------- --------------------
1 F02F05F03 # F02 description F05 description F03 description
2 F05F03 # F05 description F03 description NULL
3 F02F05 # F02 description F05 description NULL
4 F02 # F02 description NULL NULL
Oh... be careful... you have to consider how hard the I/O system needs to work when doing multiple self joins. It's a very common performance problem.
--Jeff Moden
Change is inevitable... Change for the better is not.
January 24, 2010 at 5:29 pm
gadall (1/24/2010)
This works perfectly for what I have to do.Thank you so much.
Heh... 3 solutions were given. Which one did you use?
--Jeff Moden
Change is inevitable... Change for the better is not.
January 24, 2010 at 10:48 pm
The one with the 3 self joins.
January 25, 2010 at 6:53 am
Jeff Moden (1/24/2010)
lobbymuncher (1/24/2010)
Here's a completely different way which returns the codes in the same row.Oh... be careful... you have to consider how hard the I/O system needs to work when doing multiple self joins. It's a very common performance problem.
Not near as bad as those non-sargable SUBSTRINGs ๐
Wonder if SUBSTRING(column, 1 ... is actually SARGable? Will attempt a test if time permits.
For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
Viewing 10 posts - 1 through 9 (of 9 total)
You must be logged in to reply to this topic. Login to reply