1

I need to take 2 rows of a table (it will always be 2) and have them merged into 1 row, so that these fields in the table:

BakeTime, Diameter, Size, Height

end up being something like

BakeTime1, BakeTime2, Diameter1, Diameter2, Size1, Size2, Height1, Height2

in the final result record. There is a 'unique id' field in the table, which is unique to the 2 records at a time that I want output together.

Conrad
  • 2,197
  • 28
  • 53
  • you need to tag your dmbs because it will matter for the answer. sql-server? mysql? oracle? window functions make things easier. Barring the use of window functions let us know what other fields are in the table. E..g primary and foreign keys and what column might be unique such as a timestamp. – Matt Sep 26 '16 at 17:53
  • @Matt I tagged the question with 'tsql' – Conrad Sep 26 '16 at 17:55
  • "Transact-SQL (T-SQL) is Microsoft's and Sybase's proprietary extension to the SQL" https://en.wikipedia.org/wiki/Transact-SQL also http://stackoverflow.com/questions/1301038/what-are-the-differences-between-t-sql-sql-server-and-sql I unerstand it to be sql-server but can we assume sql2012+ with window functions? – Matt Sep 26 '16 at 18:02
  • 1
    Right now you have it tagged two languages. SQL is a language not a server (in these tags) – paparazzo Sep 26 '16 at 18:03
  • Clarify 'unique id'. Do the two records share the same 'unique id' or do they each have their own 'unique id' ? – paparazzo Sep 26 '16 at 18:19
  • @Paparazzi exactly 2 records share the same 'unique id' – Conrad Sep 26 '16 at 18:31

4 Answers4

1

You should be able to use an inner join to generate a single row from the two records. Per your statements in the comments regarding an identifying column(CakeNo), something like below should work.

SELECT t1.BakeTime AS BakeTime1, t2.BakeTime as BakeTime2, t1.Diameter AS Diameter1, t2.Diameter AS Diameter2,
       t1.Size AS Size1, t2.Size AS Size2, t1.Height AS Height1, t2.Height AS Height2
FROM YourTable t1
INNER JOIN YourTable t2 ON t2.UniqueId = t1.UniqueId AND t2.CakeNo != t1.CakeNo
WHERE t1.UniqueId = 'YourIdHere' AND RIGHT(t1.CakeNo, 1) = 'A'

DISCLAIMER: I'm not entirely sure I understand your use of CakeNo, LEFT(t1.CakeNo, 1) = '1' might be necessary in place of RIGHT(t1.CakeNo, 1) = 'A'.

Derrick Moeller
  • 4,808
  • 2
  • 22
  • 48
  • I cannot assume that ``BakeTime``s will be different - they may be the same. (And even if they were different, this query returns 2 rows, with values reversed in each pair for the 2nd record) – Conrad Sep 26 '16 at 17:48
  • @Conrad instead of comparing BakeTime perhaps you have a created date column or something that would differ or an auto increment id that would distinguish 1 row from the other? Also note this query will likely duplicate your results with first row being #1 in one row and then #2 in second row...... – Matt Sep 26 '16 at 17:56
  • @Conrad you should put that CakeNo explanation in your question it will clarify it alot. I updated my answer to accommodate CakeNo but thought of it slightly different than you taking LEFT. Anyway check it out it is one of the easier methods when ROW_NUMBER() function is available. to you. – Matt Sep 26 '16 at 18:23
  • @Conrad Please see update, changes to query should address the multiple rows without the need for embedded query. – Derrick Moeller Sep 26 '16 at 18:34
  • I made a dumb typo in my previous comment; I will delete in a moment and here is the proper comment: Doing something similar worked - there is a column (CakeNo) which has '1A', '2A', '1B', '2B'; ... for the records. I wrapped FrumRoll's above code in select * from ( ) innerselect where substring(CakeNo, 1, 1) = '1' and that gives me the 1 desired record. – Conrad Sep 26 '16 at 18:40
1

If the ID are different - not clear from your question

SELECT t1.*, t2.*   // yes you need to alias actual column names
FROM YourTable t1
JOIN YourTable t2 
      ON t1.UniqueId = 1   // id1
     AND t2.UniqueId = 2   // id2

If ID are same and CakeNo are different
A lot borrowed from Matt (+1)

;WITH cte AS (
    SELECT *
         , ROW_NUMBER() OVER (PARTITION BY uniqueID ORDER BY CakeNo) as RowNum
    FROM
       TableName
  --where uniqueID = @ID -- in you only need one do it here  
)

SELECT
     c1.BakeTime as BakeTime1
    ,c2.BakeTime as BakeTime2
    ,c1.Diameter as Diameter1
    ,c2.Diameter as Diameter2
    ,c1.Size as Size1
    ,c2.Size as Size2
    ,c1.Height as Height1
    ,c2.Height as Height2
FROM
    cte c1
    left JOIN cte c2  -- in case only one row  
     ON c2.RowNum = 2
    AND c1.RowNum = 1

this works if the two CakeNo are the same
if more than two rows with same ID then would just get the first 2

paparazzo
  • 44,497
  • 23
  • 105
  • 176
1
;WITH cte AS (
    SELECT
       *
       ,LEFT(CakeNo,LEN(CakeNo) - 1) as CorrelationId
       ,ROW_NUMBER() OVER (PARTITION BY LEFT(CakeNo,LEN(CakeNo) - 1) ORDER BY CakeNo) as RowNum
    FROM
       TableName
)

SELECT
    c1.BakeTime as BakeTime1
    ,c2.BakeTime as BakeTime2
    ,c1.Diameter as Diameter1
    ,c2.Diameter as Diameter2
    ,c1.Size as Size1
    ,c2.Size as Size2
    ,c1.Height as Height1
    ,c2.Height as Height2
FROM
    cte c1
    INNER JOIN cte c2
    ON c1.CorrelationId = c2.CorrelationId
    AND c2.RowNum = 2
WHERE
    c1.RowNum = 1

Based on your comment that you can derived a correlation id from taking the 1st character of CakeNo. Because I would assume you will have more than 9 records, I thought of it as if you remove the A/B from the end you can get to your CorrelationId. I have updated my answer to reflect this.

Matt
  • 13,833
  • 2
  • 16
  • 28
0

Since you will always have only two rows try something like this

SELECT Concat(Min(baketime), ',', Max(baketime)), 
       Concat(Min(diameter), ',', Max(diameter)), 
       Concat(Min(size), ',', Max(size)), 
       Concat(Min(height), ',', Max(height)) 
FROM   yourtable 

If you are using anything less SQL Server 2012 then replace CONCAT with + operator to concatenate the strings

Update : Looks like you want this

SELECT Min(baketime), 
       Max(baketime), 
       Min(diameter), 
       Max(diameter), 
       Min(size), 
       Max(size), 
       Min(height), 
       Max(height) 
FROM   yourtable 
Pரதீப்
  • 91,748
  • 19
  • 131
  • 172