From what I see is that the programStageDataElement determines the relation between a dataElement and a programStage. All the attributes (displayInReports,skipSynchronization,externalAccess…etc) for a dataElement can be different from one program stage to another; additionally, since there can be many programStageDataElements in a programStage, each programStageDataElement must have a unique ID. Therefore, the dataElement ID must be different from the programStageDataElement ID because they are two different objects.
To make it simpler, the programStageDataElement is a description for certain attributes the dataElement will have in a programStage. I hope that the distinction is clearer now.
Please let me know if this answers your question and whether you need more info. Thank you so much! (: