3

I have this table. Considering the id starts from 0.

Table 1

ID     Letter
1        A
2        B
3        C
4        D
6        E

I need following output

Col1     Col2
NULL      A
B         C
D         NULL
E         NULL

I tried using union with id, id - 1 and id + 1, but I couldn't figure out how to get letter based on ids, also tried even odd logic but nothing worked.

Any help is appreciated.

Thank you

3
  • Can you please format the tables so that the rows and columns are clearer? Commented Oct 11, 2018 at 18:15
  • 3
    please tell us which DBMS are you using ... Commented Oct 11, 2018 at 18:19
  • Sorry, I was just formatting the tables only Commented Oct 11, 2018 at 18:25

2 Answers 2

3

You didn't post the database engine, so I'll assume PostgreSQL where the modulus operand is %.

The query should be:

select o.letter, e.letter
  from (
    select id, letter, id as base from my_table where id % 2 = 0
  ) o full outer join (
    select id, letter, (id - 1) as base from my_table where id % 2 <> 0
  ) e on e.base = o.base
  order by coalesce(o.base, e.base)

Please take the following option with a grain of salt since I don't have a way of testing it in MySQL 5.6. In the absence of a full outer join, you can perform two outer joins, and then you can union them, as in:

select * from (
  select o.base, o.letter, e.letter
    from (
      select id, letter, id as base from my_table where id % 2 = 0
    ) o left join (
      select id, letter, (id - 1) as base from my_table where id % 2 <> 0
    ) e on e.base = o.base
  union
  select e.base, o.letter, e.letter
    from (
      select id, letter, id as base from my_table where id % 2 = 0
    ) o right join (
      select id, letter, (id - 1) as base from my_table where id % 2 <> 0
    ) e on e.base = o.base
) x
order by base
Sign up to request clarification or add additional context in comments.

6 Comments

Well, that certainly gets the job done, despite scant details from OP. Well done. :)
Thank you for quick response with so less details. The logic works fine but it's MySQL and full outer join wouldn't work.
Which version of MySQL? 5.x or 8.x?
MySQL 5.6. Also I tried using left and right join then union but don't know how to proceed further
Please take a look at the second SQL. I hope it works, but it becomes increasingly uglier.
|
3

Just use conditional aggregation:

select max(case when id % 2 = 0 then letter end) as col1,
       max(case when id % 2 = 1 then letter end) as col2
from t
group by floor(id / 2);

If you prefer, you can use mod() instead of %. MySQL supports both.

3 Comments

Going to suggest an edit to correct a minor typo: floor(i / 2) should be floor(id / 2) if I'm not mistaken?
I have to say, using max() and group by floor(n / 2) is really clever - I'd never seen that used before. How did you come up with that? Had you already seen that somewhere else?
@dossy . . . No doubt, I've seen similar problems. The solution is more obvious to me than a join based solution. The problem "looks" like conditional aggregation to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.