0

I need help devising a sql script that will sort a bay item, based on the column value. If the level column value is even, then the bay ascends, but if the level column is odd, then bay descends. I have 12 levels, and 54 bays per level. So, shortened example (disregard dots after level number)

Level  Bay
    1    5
    1    4
    1   54
    1   13
    2    8
    2    3
    2    4

Result

Level  Bay
    1    4
    1    5
    1   13
    1   54
    2    8
    2    4
    2    3

Here is the script as it gives a conversion failed error when converting the varchar level to an int.

SELECT cast (SUBSTRING(cm.description, CHARINDEX('Bay:', cm.description) + 4, CHARINDEX(' ', cm.description, CHARINDEX('Bay:', cm.description)) - CHARINDEX('Bay:', cm.description) - 4) AS INT)      AS Bay,
       cast (SUBSTRING(cm.description, CHARINDEX('Level:', cm.description) + 6, CHARINDEX(' ', cm.description, CHARINDEX('Level:', cm.description)) - CHARINDEX('Level:', cm.description) - 6)AS INT) AS level
FROM   [Test].[Test].[Stations] AS cm
WHERE  ( cm.StationTypeId = '1' )
ORDER  BY CASE 'level' % 2
            WHEN 0 THEN 'bay'
            WHEN 1 THEN '-bay'
          END; 

Here is what the description column looks like for each level:

Aisle:1 Bay:1 Level:1 Side:E
  • Column references should not be in single quotes. Also you can't use column aliases defined at the same level in expressions in `ORDER BY` (if you use them they must be on their own). So probably you need something like https://dbfiddle.uk/HlCA-J0x – Martin Smith Mar 25 '23 at 19:26
  • Martin this does work; however, if I wanted to use left or full outer join, is that possible? The reason I ask is that this task is a subset of code from my entire sql script. Could you provide a version of this using a join statement? – Shuronda Hawkins Mar 25 '23 at 23:10
  • I'm sure its possible but you should edit your question demonstrating what you actually need. I'm not going to guess it and just invent and solve a fictitious requirement – Martin Smith Mar 26 '23 at 10:56
  • Hello, I tried to post the entire script but it's not allowing it. – Shuronda Hawkins Mar 26 '23 at 13:54
  • Martin I've placed a screenshot of the entire code is why I asked. – Shuronda Hawkins Mar 26 '23 at 15:02
  • https://dbfiddle.uk/4V-PWxMR ? – Luuk Apr 01 '23 at 18:09

2 Answers2

1
order by
    level,
    case level % 2
        when 0 then -bay
        when 1 then  bay
    end
shawnt00
  • 16,443
  • 3
  • 17
  • 22
1

Assuming bay is actually a string, you can't use the other answer's trick of negating it.

Instead, use separate clauses.

you also cannot sort by a calcualtion on a field created in the SELECT. Instead put it into an APPLY subquery.

SELECT
  v.bay,
  v.level
FROM Test.Stations AS cm
CROSS APPLY (
    SELECT
      cast (SUBSTRING(cm.description, CHARINDEX('Bay:', cm.description) + 4, CHARINDEX(' ', cm.description, CHARINDEX('Bay:', cm.description)) - CHARINDEX('Bay:', cm.description) - 4) AS INT)      AS Bay,
      cast (SUBSTRING(cm.description, CHARINDEX('Level:', cm.description) + 6, CHARINDEX(' ', cm.description, CHARINDEX('Level:', cm.description)) - CHARINDEX('Level:', cm.description) - 6)AS INT) AS level
) AS v
WHERE  cm.StationTypeId = '1'
order by
    v.level,
    case when v.level % 2 = 1 then bay end asc,
    case when v.level % 2 = 0 then bay end desc;
Charlieface
  • 52,284
  • 6
  • 19
  • 43