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.
| Author |
Topic |
|
yosiasz
Master Smack Fu Yak Hacker
1635 Posts |
Posted - 2010-03-29 : 14:47:35
|
GreetingsWe have one table which has both parent records and child records. There are lots of fields that will differ from parent to child. In order to display the correct parent or child value I am using the following case statement. There must be a better way. CASE WHEN child.ProID = '' OR child.ProID IS NULL THEN child.field1 ELSE parent.field1 END AS field1 CASE WHEN child.ProID = '' OR child.ProID IS NULL THEN child.field2 ELSE parent.field2 END AS field2, I was hoping to avoid as many CASE statement as the fields that might be different from parent child. Is that possible, if so if you would be kind enough to fill me in.Thanks<><><><><><><><><><><><><><><><><><><><><><><><><>If you don't have the passion to help people, you have no passion |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-29 : 15:15:16
|
If you could replace all the empty strings in the child record with NULL, then you could use:COALESCE(child.field1, parent.field1),COALESCE(child.field2, parent.field2) Coalesce return the first non-null argument passed to it. If the child.fieldx is null, then it will return parent.fieldx.However, if the child field contains an empty string, then it will return that. You could also use:ISNULL(child.field1, parent.field1),ISNULL(child.field2, parent.field2) which would achieve the same thing. ISNULL Does basically the same thing, but only takes 2 parameters. It would probably be faster the COALESCE, but I'm just guessing there.There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-03-30 : 13:58:25
|
quote: Originally posted by DBA in the making If you could replace all the empty strings in the child record with NULL, then you could use:COALESCE(child.field1, parent.field1),COALESCE(child.field2, parent.field2) Coalesce return the first non-null argument passed to it. If the child.fieldx is null, then it will return parent.fieldx.However, if the child field contains an empty string, then it will return that. You could also use:ISNULL(child.field1, parent.field1),ISNULL(child.field2, parent.field2) which would achieve the same thing. ISNULL Does basically the same thing, but only takes 2 parameters. It would probably be faster the COALESCE, but I'm just guessing there.There are 10 types of people in the world, those that understand binary, and those that don't.
The above solution doesnt make sense. OP's post was showing conditional selection of child/parent fields based on third field child.ProID.How can COALESCE or ISNULL used as above be an alternate for that? as per above suggestion it just takes first NOT NULL value out of child.field1 & parent.field1 but here third field child.ProID is not even in the frame which is not OP's scenario (at least as per initial post)------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
DBA in the making
Aged Yak Warrior
638 Posts |
Posted - 2010-03-30 : 14:09:29
|
| I appear to have misread the opening post.There are 10 types of people in the world, those that understand binary, and those that don't. |
 |
|
|
PackRat
Starting Member
26 Posts |
Posted - 2010-03-30 : 17:44:12
|
I believe I understand where you're trying to end up on this one; my appologies if not.spent a bit more time on this than I ought to have, I've certainly been down this road before and most often ended up at some alternative revision or gone ahead with the case statement.followed it through to its conclusion this time and before I present a the solution, which is not perfect, I'd pre-emtively recomend going with the case statement for legibility or some other alternative to the code I present below.I didn't have a lot to go on for testing so I whipped up a test scenario, probably isn't an exact model but ought to be close enough to illustrate the solution and the inherent problems with it.to summarize; you can get to a solution using ISNULL and NULLIF (i'll spare you the gory details), but the solution breaks if the data in the child fields contains empty strings or nulls. Not to mention it is ugly as sin.DECLARE @parent TABLE( PK TINYINT , field1 VARCHAR(100) , field2 VARCHAR(100));INSERT @parent SELECT 0,'pf1','pf2';DECLARE @child TABLE( FK TINYINT , IX TINYINT NOT NULL PRIMARY KEY , ProID VARCHAR(100) , field1 VARCHAR(100) , field2 VARCHAR(100));INSERT @child SELECT 0, 1, 'A' ,'cf1' ,'cf2' UNION ALL -- test 1 SELECT 0, 2, 'B' ,'cf1' ,'cf2' UNION ALL -- test 2 SELECT 0, 3, '' ,'cf1' ,'cf2' UNION ALL -- test 3 SELECT 0, 4, NULL ,'cf1' ,'cf2' UNION ALL -- test 4 SELECT 0, 5, '' ,'' ,NULL UNION ALL -- control 1; ProID is an empty string, --child fields should come through as empty/null, but will be replaced by parent fields instead SELECT 0, 6, NULL ,NULL ,'' UNION ALL -- control 2; ProID is null, --child fields should come through as empty/null, but the null value in child field 1 will be replaced by the parent field SELECT 0, 7, 'C' ,'' ,NULL UNION ALL -- control 3; works as advertized SELECT 0, 8, 'D' ,NULL ,'' -- control 4; works as advertizedSELECT [IX] =child.ix ,[ProID] =child.ProID ,[field1] =ISNULL(NULLIF(ISNULL(NULLIF(ISNULL(child.ProID, ''), ''), child.field1), child.ProID), parent.field1) ,[field2] =ISNULL(NULLIF(ISNULL(NULLIF(ISNULL(child.ProID, ''), ''), child.field2), child.ProID), parent.field2)FROM @parent parent JOIN @child child ON parent.PK=child.FK; result:IX ProID F1 F21 A pf1 pf2 -- correct2 B pf1 pf2 -- correct3 cf1 cf2 -- correct4 NULL cf1 cf2 -- correct5 pf1 pf2 -- F1 should be NULL, F2 should be ''6 NULL pf1 -- F1 should be '', F2 is correct7 C pf1 pf2 -- correct8 D pf1 pf2 -- correct my only other recomendation is that you could try and abbreviate the case statement a bit and make it more legible:,CASE ISNULL(child.ProID, '') WHEN '' THEN child.field1 ELSE parent.field1 END AS field1 ,CASE ISNULL(child.ProID, '') WHEN '' THEN child.field2 ELSE parent.field2 END AS field2 lot easier to read and infalible with regards to the bug in the first blockwrote this on my TRS-80 COCO |
 |
|
|
tkizer
Almighty SQL Goddess
38200 Posts |
|
|
DonAtWork
Master Smack Fu Yak Hacker
2167 Posts |
Posted - 2010-03-31 : 12:05:29
|
quote: Originally posted by yosiasz GreetingsWe have one table which has both parent records and child records.
quote: Originally posted by PackRat I believe I understand where you're trying to end up on this one; my appologies if not.[code]DECLARE @parent TABLE( PK TINYINT , field1 VARCHAR(100) , field2 VARCHAR(100));INSERT @parent SELECT 0,'pf1','pf2';DECLARE @child TABLE( FK TINYINT , IX TINYINT NOT NULL PRIMARY KEY , ProID VARCHAR(100) , field1 VARCHAR(100) , field2 VARCHAR(100));
Your solution shows 2 tables, where his original problem has ONE table. Perhaps the OP can follow the HOW TO ASK link in my signature, and provide some DDL and sample data and output?http://weblogs.sqlteam.com/jeffs/archive/2008/05/13/question-needed-not-answer.aspxHow to ask: http://weblogs.sqlteam.com/brettk/archive/2005/05/25/5276.aspxFor ultra basic questions, follow these links.http://www.sql-tutorial.net/ http://www.firstsql.com/tutor.htm http://www.w3schools.com/sql/default.asp |
 |
|
|
PackRat
Starting Member
26 Posts |
Posted - 2010-03-31 : 12:46:22
|
| looked to me that the original had two table references; parent and childparent.field1child.field1I made that inference since the dot notation wasn't encapulated by brackets:[parent.field1][child.field1]thought the author might have meant 'one query' rather than 'one table'. ... or maybe its a table joined on itself, mysteries abound._____________________________wrote this on my TRS-80 COCO4<PakRat/> |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-03-31 : 13:27:08
|
| it does seem like he meant one query seeing the multiple aliases------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
yosiasz
Master Smack Fu Yak Hacker
1635 Posts |
Posted - 2010-04-12 : 14:46:56
|
sorry folks !! been away but issue is still around so here is some DDL. it is one table, with parent and child rows in same tablecreate table parent(project int, ref int, field1 varchar(12), field2 int, amount money)--'parent row'INSERT INTO [dbo].[parent] ([project] ,[ref] ,[field1] ,[field2] ,[amount]) VALUES (1 ,222 ,'Credit' ,12354 ,50)----'child rows' in same tableINSERT INTO [dbo].[parent] ([project] ,[ref] ,[field1] ,[field2] ,[amount]) VALUES (NULL ,222 ,'Credit' ,12354 ,50)INSERT INTO [dbo].[parent] ([project] ,[ref] ,[field1] ,[field2] ,[amount]) VALUES (NULL ,222 ,'Credit' ,12354 ,56789) <><><><><><><><><><><><><><><><><><><><><><><><><>If you don't have the passion to help people, you have no passion |
 |
|
|
visakh16
Very Important crosS Applying yaK Herder
52326 Posts |
Posted - 2010-04-12 : 14:58:37
|
| so what should be your output?------------------------------------------------------------------------------------------------------SQL Server MVPhttp://visakhm.blogspot.com/ |
 |
|
|
|
|
|
|
|