tbaseflug
asked on
Sort - parent records but keep child records "under" them
You'll need to artificially create a sort field that can be sorted properly
Using your above example,
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + cast(ContractMasterID as varchar(50)) + cast(ContractID as varchar(50)) as MyCompositeKey
Order by MyCompositKey
Depending on data min/max you may need to push contractMasterID and ContractID into a space filled right set condition to get what you need.
Using your above example,
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + cast(ContractMasterID as varchar(50)) + cast(ContractID as varchar(50)) as MyCompositeKey
Order by MyCompositKey
Depending on data min/max you may need to push contractMasterID and ContractID into a space filled right set condition to get what you need.
This might help
CREATE FUNCTION [dbo].[ZeroFillRightSet] (
@Valu int,
@CharsWide int
)
RETURNS varchar(20)
AS
BEGIN
DECLARE @Ret varchar(20),
@BigInt bigint
select @BigInt= (@Valu + 100000000000000000)
select @Ret = cast(@BigInt as varchar(20))
select @Ret = RIGHT(@Ret, @CharsWide)
RETURN @Ret
END
so ...
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + cast(ContractMasterID as varchar(50)) + cast(ContractID as varchar(50)) as MyCompositeKey
Order by MyCompositKey
becomes
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + dbo.ZeroFillRightSet(Contr actMasterI D, 10) + dbo.ZeroFillRightSet(Contr actID, 10) as MyCompositeKey
Order by MyCompositKey
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + cast(ContractMasterID as varchar(50)) + cast(ContractID as varchar(50)) as MyCompositeKey
Order by MyCompositKey
becomes
select
contractMasterID,
ContractID,
Contract,
[Contract Parent],
SortID,
Cast(Contract as varchar(500)) + dbo.ZeroFillRightSet(Contr
Order by MyCompositKey
And using your snippet ...
SELECT [contractMasterID], [Contract ID],[Contract],[Contract Parent], sortID, totalCharge,
Cast(Contract as varchar(500)) + dbo.ZeroFillRightSet(ContractMasterID, 10) + dbo.ZeroFillRightSet(ContractID, 10) as MyCompositeKey
FROM (
SELECT
contractID AS [Contract ID]
,CASE
WHEN isParent = 1 THEN InsuranceCompanyName + ' - Parent'
ELSE contractNumber + ' - ' + InsuranceCompanyName END AS [Contract],
CASE WHEN ContractMasterID IS NOT NULL AND isParent IS NULL or isParent = 0
THEN (SELECT '('+ CAST(contractID AS varchar(30))+ ') ' + InsuranceCompanyName + ' - Parent' FROM cm_tblContractSummary x WHERE x.contractID = c.contractMasterID)
WHEN isParent = 1 THEN 'Parent' ELSE 'No Parent Assigned'END AS [Contract Parent]
,contractMasterID
,1 AS sortID
,SUM(ISNULL(defaultINpatientCharge,0) + ISNULL(defaultOutpatientCharge,0) + ISNULL(defaultEmergencyCharge,0)
+ ISNULL(defaultUrgentCareCharge,0) + ISNULL(defaultNonPatientCharge,0) + ISNULL(defaultAmbulatoryCharge,0)) AS [totalCharge]
FROM cm_tblContractSummary c
WHERE db = 'dbAlaskaNativePhysicn'
GROUP BY contractID, isParent, insuranceCompanyName, contractNumber, contractMasterID
) z
WHERE [Contract Parent] <> 'No Parent Assigned'
ORDER BY MyCompositeKey
ASKER
Including ContractMasterID and ContractID in the sort field prevents two like named contracts from sorting as a single. For example, if you had two AETNA's, one with ContractMasterID = 123 and ther other with ContractMasterID = 345 the resultant sort fields would be ...
AETNA00000123###ContractID###
and
AETNA00000345###ContractID###
AETNA00000123###ContractID###
and
AETNA00000345###ContractID###
May I see the TSQL which produced above result?
ASKER
SELECT [contractMasterID], [Contract ID],[Contract],[Contract Parent], sortID, totalCharge,
Cast(Contract as varchar(500)) + dbo.ZeroFillRightSet(Contr actMasterI D, 10) + dbo.ZeroFillRightSet([Cont ract ID], 10) as MyCompositeKey
FROM (
SELECT
contractID AS [Contract ID]
,CASE
WHEN isParent = 1 THEN InsuranceCompanyName + ' - Parent'
ELSE contractNumber + ' - ' + InsuranceCompanyName END AS [Contract],
CASE WHEN ContractMasterID IS NOT NULL AND isParent IS NULL or isParent = 0
THEN (SELECT '('+ CAST(contractID AS varchar(30))+ ') ' + InsuranceCompanyName + ' - Parent' FROM cm_tblContractSummary x WHERE x.contractID = c.contractMasterID)
WHEN isParent = 1 THEN 'Parent' ELSE 'No Parent Assigned'END AS [Contract Parent]
,contractMasterID
,1 AS sortID
,SUM(ISNULL(defaultINpatie ntCharge,0 ) + ISNULL(defaultOutpatientCh arge,0) + ISNULL(defaultEmergencyCha rge,0)
+ ISNULL(defaultUrgentCareCh arge,0) + ISNULL(defaultNonPatientCh arge,0) + ISNULL(defaultAmbulatoryCh arge,0)) AS [totalCharge]
FROM cm_tblContractSummary c
WHERE db = 'dbAlaskaNativePhysicn'
GROUP BY contractID, isParent, insuranceCompanyName, contractNumber, contractMasterID
) z
WHERE [Contract Parent] <> 'No Parent Assigned'
ORDER BY MyCompositeKey
Cast(Contract as varchar(500)) + dbo.ZeroFillRightSet(Contr
FROM (
SELECT
contractID AS [Contract ID]
,CASE
WHEN isParent = 1 THEN InsuranceCompanyName + ' - Parent'
ELSE contractNumber + ' - ' + InsuranceCompanyName END AS [Contract],
CASE WHEN ContractMasterID IS NOT NULL AND isParent IS NULL or isParent = 0
THEN (SELECT '('+ CAST(contractID AS varchar(30))+ ') ' + InsuranceCompanyName + ' - Parent' FROM cm_tblContractSummary x WHERE x.contractID = c.contractMasterID)
WHEN isParent = 1 THEN 'Parent' ELSE 'No Parent Assigned'END AS [Contract Parent]
,contractMasterID
,1 AS sortID
,SUM(ISNULL(defaultINpatie
+ ISNULL(defaultUrgentCareCh
FROM cm_tblContractSummary c
WHERE db = 'dbAlaskaNativePhysicn'
GROUP BY contractID, isParent, insuranceCompanyName, contractNumber, contractMasterID
) z
WHERE [Contract Parent] <> 'No Parent Assigned'
ORDER BY MyCompositeKey
hmmmmm got it
how many rows does this query return? 10 million? I hope not, because you're going to need a query that references itself.
Give me a couple of minutes to work up a sample.
how many rows does this query return? 10 million? I hope not, because you're going to need a query that references itself.
Give me a couple of minutes to work up a sample.
ASKER
usually less than 1000 total rows
First off ... remember ... I do NOT have an underlying DB to test this on (grin) meaning there may be syntax errors.
CREATE TABLE #LocTable
(
[contractMasterID] int,
[Contract ID] int,
[Contract] varchar(500),
[Contract Parent] varchar(500),
sortID int,
totalCharge money, -- not sure this is right type
CompositeKey varchar(1000)
)
CREATE UNIQUE CLUSTERED INDEX IX_1 on #LocTable (contractMasterID)
insert ([contractMasterID], [Contract ID], [Contract], [Contract Parent], sortID, totalCharge)
SELECT [contractMasterID], [Contract ID],[Contract],[Contract Parent], sortID, totalCharge,
FROM (
SELECT
contractID AS [Contract ID]
,CASE
WHEN isParent = 1 THEN InsuranceCompanyName + ' - Parent'
ELSE contractNumber + ' - ' + InsuranceCompanyName END AS [Contract],
CASE WHEN ContractMasterID IS NOT NULL AND isParent IS NULL or isParent = 0
THEN (SELECT '('+ CAST(contractID AS varchar(30))+ ') ' + InsuranceCompanyName + ' - Parent' FROM cm_tblContractSummary x WHERE x.contractID = c.contractMasterID)
WHEN isParent = 1 THEN 'Parent' ELSE 'No Parent Assigned'END AS [Contract Parent]
,contractMasterID
,1 AS sortID
,SUM(ISNULL(defaultINpatientCharge,0) + ISNULL(defaultOutpatientCharge,0) + ISNULL(defaultEmergencyCharge,0)
+ ISNULL(defaultUrgentCareCharge,0) + ISNULL(defaultNonPatientCharge,0) + ISNULL(defaultAmbulatoryCharge,0)) AS [totalCharge]
FROM cm_tblContractSummary c
WHERE db = 'dbAlaskaNativePhysicn'
GROUP BY contractID, isParent, insuranceCompanyName, contractNumber, contractMasterID
) z
WHERE [Contract Parent] <> 'No Parent Assigned'
update a
set a.CompositeKey =
Cast(b.Contract as varchar(500)) +
dbo.ZeroFillRightSet(a.ContractMasterID, 10) +
dbo.ZeroFillRightSet(a.ContractID, 10)
from #LocTable a
inner join #LocTable b
on a.contractMasterID = b.contractMasterID
and b.[Contract Parent]='Parent'
Select * from #LocTable order by CompositeKey
Told ya! (smile)
Line 13 should read
insert #LocTable ([contractMasterID], [Contract ID], [Contract], [Contract Parent], sortID, totalCharge)
Line 13 should read
insert #LocTable ([contractMasterID], [Contract ID], [Contract], [Contract Parent], sortID, totalCharge)
ASKER
and ...
line 11 may need to read
CREATE INDEX IX_1 on #LocTable (contractMasterID)
line 11 may need to read
CREATE INDEX IX_1 on #LocTable (contractMasterID)
Wait one ...
Try this
CREATE TABLE #LocTable
(
[contractMasterID] int,
[Contract ID] int,
[Contract] varchar(500),
[Contract Parent] varchar(500),
sortID int,
totalCharge money, -- not sure this is right type
CompositeKey varchar(1000),
IsParent bit
)
CREATE INDEX IX_1 on #LocTable (contractMasterID)
insert #LocTable([contractMasterID], [Contract ID], [Contract], [Contract Parent], sortID, totalCharge)
SELECT [contractMasterID], [Contract ID],[Contract],[Contract Parent], sortID, totalCharge,
FROM (
SELECT
contractID AS [Contract ID]
,CASE
WHEN isParent = 1 THEN InsuranceCompanyName + ' - Parent'
ELSE contractNumber + ' - ' + InsuranceCompanyName END AS [Contract],
CASE WHEN ContractMasterID IS NOT NULL AND isParent IS NULL or isParent = 0
THEN (SELECT '('+ CAST(contractID AS varchar(30))+ ') ' + InsuranceCompanyName + ' - Parent' FROM cm_tblContractSummary x WHERE x.contractID = c.contractMasterID)
WHEN isParent = 1 THEN 'Parent' ELSE 'No Parent Assigned'END AS [Contract Parent]
,contractMasterID
,1 AS sortID
,SUM(ISNULL(defaultINpatientCharge,0) + ISNULL(defaultOutpatientCharge,0) + ISNULL(defaultEmergencyCharge,0)
+ ISNULL(defaultUrgentCareCharge,0) + ISNULL(defaultNonPatientCharge,0) + ISNULL(defaultAmbulatoryCharge,0)) AS [totalCharge]
FROM cm_tblContractSummary c
WHERE db = 'dbAlaskaNativePhysicn'
GROUP BY contractID, isParent, insuranceCompanyName, contractNumber, contractMasterID
) z
WHERE [Contract Parent] <> 'No Parent Assigned'
update a
set a.CompositeKey =
Cast(b.Contract as varchar(500)) +
dbo.ZeroFillRightSet(a.ContractMasterID, 10) +
dbo.ZeroFillRightSet(a.ContractID, 10)
from #LocTable a
inner join #LocTable b
on a.contractMasterID = b.contractMasterID
and b.[Contract Parent]='Parent'
Update #LocTable set
IsParent = CASE
WHEN [Contract Parent]='Parent' THEN 1
ELSE 0
END
Select * from #LocTable order by IsParent desc, CompositeKey
opps - line 53 should be reversed
Select * from #LocTable order by CompositeKey, IsParent desc
Select * from #LocTable order by CompositeKey, IsParent desc
ASKER
Whoops - not sure if I was clear - instead of (in previous post) - which essentially works - but instead of:
child
child
parent
I wanted it:
parent
child
child
child
child
parent
I wanted it:
parent
child
child
By The Way ... looks like you work for an insurance company - What da HECK you doing working at THIS time of night?
Yeah - try my post
opps - line 53 should be reversed
Select * from #LocTable order by CompositeKey, IsParent desc
opps - line 53 should be reversed
Select * from #LocTable order by CompositeKey, IsParent desc
ASKER
Okay ... question
If the PARENT is moved to the TOP, what ORDER should the underlying children take?
numeric [Contract ID] or
alpha [Contract]
If the PARENT is moved to the TOP, what ORDER should the underlying children take?
numeric [Contract ID] or
alpha [Contract]
ASKER
alpha [Contract]
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh, also reversed IsParent update from 1-0 to 0-1 to make sure it sorts right
Opps - line 12 is missing a paren
cast(a.[Contract] as varchar(500))
cast(a.[Contract] as varchar(500))
ASKER
WOW! Awesome! Thanks so much! Works perfectly! Saved my bacon and lets me go home finally... Thanks!
Welcome ...
I use this technique a lot, create an intermediate table, then slice-n-dice the intermediate table a dozen ways to sunday.
Later
I'm gonna go eat dinner!
I use this technique a lot, create an intermediate table, then slice-n-dice the intermediate table a dozen ways to sunday.
Later
I'm gonna go eat dinner!
ASKER
Learned something new tonight - much thanks!
ASKER
Open in new window