How to split and merge records?
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.
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?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
add a comment |
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.
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?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
Can you explain what "based on the TYPE column as below" means?
– Jacek Laskowski
Jun 27 '17 at 0:53
add a comment |
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.
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?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
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.
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?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
apache-spark apache-spark-sql
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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!
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 usedwithColumnto createfullParentsto match the number of columns incustomers. 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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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!
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 usedwithColumnto createfullParentsto match the number of columns incustomers. 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
add a comment |
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!
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 usedwithColumnto createfullParentsto match the number of columns incustomers. 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
add a comment |
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!
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!
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 usedwithColumnto createfullParentsto match the number of columns incustomers. 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
add a comment |
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 usedwithColumnto createfullParentsto match the number of columns incustomers. 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Can you explain what "based on the TYPE column as below" means?
– Jacek Laskowski
Jun 27 '17 at 0:53