How to split and merge records?










1















I have a CSV file and the data for customer_id looks like below.



CUSTID,LOC,PRODNAME,UNITS,TYPE,PURCHASE_DATE
123,"SA","PROD1",1000,"PAY","20-DEC-2016"
123,"SA","PROD2",500,"REC","31-AUG-2016"


And this has to be converted into three records one as a Parent record and other two as Child records based on the TYPE column as below. This has to finally go into another CSV file.



ROWTYPE,CUSTID,LOC,TYPE,PRODUCT_NAME,UNITS,PURCHASE_DATE
PARENT,123,"SA"
CHILD,123,"SA","PAY","PROD1","20-DEC-2016"
CHILD,123,"SA","REC","PROD2","31-AUG-2016"


Two more things on the same task.



  1. My output CSV file has only one header just for the parent record and child records could have either more or less fields than the parent record.
    Because of this reason I cannot UNION parent and childs so I just converted all the Dataframes into RDD and did a union on that.
    So to just know, if this has to be done using Dataframes, how would I do it?


  2. Then finally I need to create a CSV file in some specific order based on CUSTID and TYPE field. I know this is easy incase of Dataframes but since I converted them to RDD's I did the following but don't know if it's an optimum approach.


Even this one doesn't work when I repartition and merge the output CSV file as the ordering goes for a toss.










share|improve this question
























  • Can you explain what "based on the TYPE column as below" means?

    – Jacek Laskowski
    Jun 27 '17 at 0:53















1















I have a CSV file and the data for customer_id looks like below.



CUSTID,LOC,PRODNAME,UNITS,TYPE,PURCHASE_DATE
123,"SA","PROD1",1000,"PAY","20-DEC-2016"
123,"SA","PROD2",500,"REC","31-AUG-2016"


And this has to be converted into three records one as a Parent record and other two as Child records based on the TYPE column as below. This has to finally go into another CSV file.



ROWTYPE,CUSTID,LOC,TYPE,PRODUCT_NAME,UNITS,PURCHASE_DATE
PARENT,123,"SA"
CHILD,123,"SA","PAY","PROD1","20-DEC-2016"
CHILD,123,"SA","REC","PROD2","31-AUG-2016"


Two more things on the same task.



  1. My output CSV file has only one header just for the parent record and child records could have either more or less fields than the parent record.
    Because of this reason I cannot UNION parent and childs so I just converted all the Dataframes into RDD and did a union on that.
    So to just know, if this has to be done using Dataframes, how would I do it?


  2. Then finally I need to create a CSV file in some specific order based on CUSTID and TYPE field. I know this is easy incase of Dataframes but since I converted them to RDD's I did the following but don't know if it's an optimum approach.


Even this one doesn't work when I repartition and merge the output CSV file as the ordering goes for a toss.










share|improve this question
























  • Can you explain what "based on the TYPE column as below" means?

    – Jacek Laskowski
    Jun 27 '17 at 0:53













1












1








1


1






I have a CSV file and the data for customer_id looks like below.



CUSTID,LOC,PRODNAME,UNITS,TYPE,PURCHASE_DATE
123,"SA","PROD1",1000,"PAY","20-DEC-2016"
123,"SA","PROD2",500,"REC","31-AUG-2016"


And this has to be converted into three records one as a Parent record and other two as Child records based on the TYPE column as below. This has to finally go into another CSV file.



ROWTYPE,CUSTID,LOC,TYPE,PRODUCT_NAME,UNITS,PURCHASE_DATE
PARENT,123,"SA"
CHILD,123,"SA","PAY","PROD1","20-DEC-2016"
CHILD,123,"SA","REC","PROD2","31-AUG-2016"


Two more things on the same task.



  1. My output CSV file has only one header just for the parent record and child records could have either more or less fields than the parent record.
    Because of this reason I cannot UNION parent and childs so I just converted all the Dataframes into RDD and did a union on that.
    So to just know, if this has to be done using Dataframes, how would I do it?


  2. Then finally I need to create a CSV file in some specific order based on CUSTID and TYPE field. I know this is easy incase of Dataframes but since I converted them to RDD's I did the following but don't know if it's an optimum approach.


Even this one doesn't work when I repartition and merge the output CSV file as the ordering goes for a toss.










share|improve this question
















I have a CSV file and the data for customer_id looks like below.



CUSTID,LOC,PRODNAME,UNITS,TYPE,PURCHASE_DATE
123,"SA","PROD1",1000,"PAY","20-DEC-2016"
123,"SA","PROD2",500,"REC","31-AUG-2016"


And this has to be converted into three records one as a Parent record and other two as Child records based on the TYPE column as below. This has to finally go into another CSV file.



ROWTYPE,CUSTID,LOC,TYPE,PRODUCT_NAME,UNITS,PURCHASE_DATE
PARENT,123,"SA"
CHILD,123,"SA","PAY","PROD1","20-DEC-2016"
CHILD,123,"SA","REC","PROD2","31-AUG-2016"


Two more things on the same task.



  1. My output CSV file has only one header just for the parent record and child records could have either more or less fields than the parent record.
    Because of this reason I cannot UNION parent and childs so I just converted all the Dataframes into RDD and did a union on that.
    So to just know, if this has to be done using Dataframes, how would I do it?


  2. Then finally I need to create a CSV file in some specific order based on CUSTID and TYPE field. I know this is easy incase of Dataframes but since I converted them to RDD's I did the following but don't know if it's an optimum approach.


Even this one doesn't work when I repartition and merge the output CSV file as the ordering goes for a toss.







apache-spark apache-spark-sql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 19:02







1pluszara

















asked Jun 26 '17 at 19:31









1pluszara1pluszara

722416




722416












  • Can you explain what "based on the TYPE column as below" means?

    – Jacek Laskowski
    Jun 27 '17 at 0:53

















  • Can you explain what "based on the TYPE column as below" means?

    – Jacek Laskowski
    Jun 27 '17 at 0:53
















Can you explain what "based on the TYPE column as below" means?

– Jacek Laskowski
Jun 27 '17 at 0:53





Can you explain what "based on the TYPE column as below" means?

– Jacek Laskowski
Jun 27 '17 at 0:53












1 Answer
1






active

oldest

votes


















1














Getting PARENT,123,"SA" seems easy by a simple query with groupBy.



val parents = customers.
select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT| 123| SA|
+-------+------+---+


With that, you union it with the rest to get the final PARENT and CHILD records.



Since union can only be performed on tables with the same number of columns, and customers has 6 columns and parents has 3 columns, you have to make the datasets match.



val fullParents = parents.
withColumn("PRODUCT_NAME", lit("")).
withColumn("UNITS", lit("")).
withColumn("TYPE", lit("")).
withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
+-------+------+---+------------+-----+----+-------------+


Let's add the ROWTYPE as CHILD to customers.



val rowtypedCustomers = customers.
select(lit("CHILD") as "ROWTYPE", customers("*")).
withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+


Writing it as a CSV is as simple as the following query:



solution.write.csv("solution.csv")


Done. Congrats!






share|improve this answer























  • If the answer helped, please accept it (and possibly upvote too). Thanks!

    – Jacek Laskowski
    Jun 27 '17 at 15:08











  • Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

    – Jacek Laskowski
    Jun 28 '17 at 16:42










Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44767339%2fhow-to-split-and-merge-records%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Getting PARENT,123,"SA" seems easy by a simple query with groupBy.



val parents = customers.
select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT| 123| SA|
+-------+------+---+


With that, you union it with the rest to get the final PARENT and CHILD records.



Since union can only be performed on tables with the same number of columns, and customers has 6 columns and parents has 3 columns, you have to make the datasets match.



val fullParents = parents.
withColumn("PRODUCT_NAME", lit("")).
withColumn("UNITS", lit("")).
withColumn("TYPE", lit("")).
withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
+-------+------+---+------------+-----+----+-------------+


Let's add the ROWTYPE as CHILD to customers.



val rowtypedCustomers = customers.
select(lit("CHILD") as "ROWTYPE", customers("*")).
withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+


Writing it as a CSV is as simple as the following query:



solution.write.csv("solution.csv")


Done. Congrats!






share|improve this answer























  • If the answer helped, please accept it (and possibly upvote too). Thanks!

    – Jacek Laskowski
    Jun 27 '17 at 15:08











  • Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

    – Jacek Laskowski
    Jun 28 '17 at 16:42















1














Getting PARENT,123,"SA" seems easy by a simple query with groupBy.



val parents = customers.
select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT| 123| SA|
+-------+------+---+


With that, you union it with the rest to get the final PARENT and CHILD records.



Since union can only be performed on tables with the same number of columns, and customers has 6 columns and parents has 3 columns, you have to make the datasets match.



val fullParents = parents.
withColumn("PRODUCT_NAME", lit("")).
withColumn("UNITS", lit("")).
withColumn("TYPE", lit("")).
withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
+-------+------+---+------------+-----+----+-------------+


Let's add the ROWTYPE as CHILD to customers.



val rowtypedCustomers = customers.
select(lit("CHILD") as "ROWTYPE", customers("*")).
withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+


Writing it as a CSV is as simple as the following query:



solution.write.csv("solution.csv")


Done. Congrats!






share|improve this answer























  • If the answer helped, please accept it (and possibly upvote too). Thanks!

    – Jacek Laskowski
    Jun 27 '17 at 15:08











  • Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

    – Jacek Laskowski
    Jun 28 '17 at 16:42













1












1








1







Getting PARENT,123,"SA" seems easy by a simple query with groupBy.



val parents = customers.
select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT| 123| SA|
+-------+------+---+


With that, you union it with the rest to get the final PARENT and CHILD records.



Since union can only be performed on tables with the same number of columns, and customers has 6 columns and parents has 3 columns, you have to make the datasets match.



val fullParents = parents.
withColumn("PRODUCT_NAME", lit("")).
withColumn("UNITS", lit("")).
withColumn("TYPE", lit("")).
withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
+-------+------+---+------------+-----+----+-------------+


Let's add the ROWTYPE as CHILD to customers.



val rowtypedCustomers = customers.
select(lit("CHILD") as "ROWTYPE", customers("*")).
withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+


Writing it as a CSV is as simple as the following query:



solution.write.csv("solution.csv")


Done. Congrats!






share|improve this answer













Getting PARENT,123,"SA" seems easy by a simple query with groupBy.



val parents = customers.
select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT| 123| SA|
+-------+------+---+


With that, you union it with the rest to get the final PARENT and CHILD records.



Since union can only be performed on tables with the same number of columns, and customers has 6 columns and parents has 3 columns, you have to make the datasets match.



val fullParents = parents.
withColumn("PRODUCT_NAME", lit("")).
withColumn("UNITS", lit("")).
withColumn("TYPE", lit("")).
withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
+-------+------+---+------------+-----+----+-------------+


Let's add the ROWTYPE as CHILD to customers.



val rowtypedCustomers = customers.
select(lit("CHILD") as "ROWTYPE", customers("*")).
withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT| 123| SA| | | | |
| CHILD| 123| SA| PROD1| 1000| PAY| 20-DEC-2016|
| CHILD| 123| SA| PROD2| 500| REC| 31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+


Writing it as a CSV is as simple as the following query:



solution.write.csv("solution.csv")


Done. Congrats!







share|improve this answer












share|improve this answer



share|improve this answer










answered Jun 27 '17 at 0:51









Jacek LaskowskiJacek Laskowski

45k18132270




45k18132270












  • If the answer helped, please accept it (and possibly upvote too). Thanks!

    – Jacek Laskowski
    Jun 27 '17 at 15:08











  • Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

    – Jacek Laskowski
    Jun 28 '17 at 16:42

















  • If the answer helped, please accept it (and possibly upvote too). Thanks!

    – Jacek Laskowski
    Jun 27 '17 at 15:08











  • Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

    – Jacek Laskowski
    Jun 28 '17 at 16:42
















If the answer helped, please accept it (and possibly upvote too). Thanks!

– Jacek Laskowski
Jun 27 '17 at 15:08





If the answer helped, please accept it (and possibly upvote too). Thanks!

– Jacek Laskowski
Jun 27 '17 at 15:08













Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

– Jacek Laskowski
Jun 28 '17 at 16:42





Re 1. That's why I used withColumn to create fullParents to match the number of columns in customers. Re 2. That's a separate question which I recommend asking as a separate question on StackOverflow. Please accept the answer if the answer helped.

– Jacek Laskowski
Jun 28 '17 at 16:42



















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f44767339%2fhow-to-split-and-merge-records%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

What does pagestruct do in Eviews?

Dutch intervention in Lombok and Karangasem

Channel Islands