SQL: Как получить строку, даже если SELECT CASE не запускается? - PullRequest
0 голосов
/ 05 сентября 2011

У меня есть следующий SELECT ...

    SELECT CASE WHEN cola < 0 THEN '-'
                WHEN cola > 0 THEN '+'
                ELSE '='
           END
           SUM(colb), SUM(colc), SUM(cold),
           MAX(CASE WHEN cola < 0 THEN 1
                    WHEN cola > 0 THEN 3
                    ELSE 2
              ) AS Sort
      FROM Table1
     WHERE this = that
  GROUP BY CASE WHEN cola < 0 THEN '-'
                WHEN cola > 0 THEN '+'
                ELSE '=' END
  ORDER BY cold

Вот что я получаю:

cola    colb   colc   cold
-        1       2     1
+        13      0     3

Это то, что я хочу:

cola    colb   colc   cold
-        1       2     1
=        0       0     2
+        13      0     3

Когда я получаю набор результатов, у меня есть строки '+' и '-', но нет строки '=', потому что не было никаких значений '0', чтобы вызвать ELSE. Как я могу установить его так, чтобы, если это так, то в моем операторе SELECT все равно была строка '='?

Спасибо! * Если требуется больше выбора, просто дайте мне знать.

Ответы [ 2 ]

3 голосов
/ 05 сентября 2011
SELECT
       foo.symbol,
       SUM(colb), SUM(colc), SUM(cold)
  FROM
        (SELECT '-' AS Symbol, 1 As Sort 
         UNION ALL SELECT '=', 2
         UNION ALL SELECT '+', 3
        ) foo
        LEFT JOIN
        Table1 ON foo.symbol = CASE WHEN cola < 0 THEN '-'
            WHEN cola > 0 THEN '+'
            ELSE '='
       END
 WHERE this = that
GROUP BY foo.symbol, foo.sort
ORDER BY foo.sort

Вам также может понадобиться производная таблица для Table1, чтобы правильно применить фильтр. Вы можете вставить этот случай в это

Редактировать, после комментариев, еще проще благодаря @ WReach

SELECT
       foo.SignAndSort,
       SUM(colb), SUM(colc), SUM(cold)
  FROM
        (SELECT '-1' AS SignAndSort
         UNION ALL SELECT '0'
         UNION ALL SELECT '-1'
        ) foo
        LEFT JOIN
        Table1 ON foo.SignAndSort = SIGN(cola)
 WHERE this = that
GROUP BY foo.SignAndSort
ORDER BY foo.SignAndSort
1 голос
/ 05 сентября 2011

Звучит так, как будто вы хотите, чтобы 0 был представлен, хотя этого значения не было в столбце cola.

Мой первый подход:

  • собрать сумму в производной таблице (t)
  • СОЕДИНИТЕ, что против другой производной таблицы с единственной строкой, содержащей Вашу строку равенства. (* 1 010 *)
  • ВЫБРАТЬ МАКС, который отфильтровывает дубликаты, когда UNION ALL создает дубликат в случае, если в таблице действительно существуют равные t.
SELECT  MySymbol, MAX(MySumB) AS MySumB, 
                  MAX(MySumC) AS MySumC, 
                  MAX(MySumD) AS MySumD
FROM (    
        SELECT MySymbol,MySumB,MySumC,MySumD
        FROM (
                SELECT CASE WHEN cola < 0 THEN '-'
                        WHEN cola > 0 THEN '+'
                        ELSE '='
                   END  AS MySymbol,
                   SUM(colb) AS MySumB, SUM(colc) AS MySumC, SUM(cold) AS MySumD,
                   MAX(CASE WHEN cola < 0 THEN 1
                            WHEN cola > 0 THEN 3
                            ELSE 2
                      ) AS Sort
                 FROM Table1
                 WHERE this = that
                 GROUP BY CASE WHEN cola < 0 THEN '-'
                            WHEN cola > 0 THEN '+'
                            ELSE '=' END                
            UNION  ALL
            SELECT '=' AS MySymbol, 0,0,0,0
        )  t
) t2
GROUP BY MySymbol
ORDER BY MySumD

Это могло бы быть немного более трудным решением, если бы мы знали, какую СУБД вы используете. Выше приведено соответствие ANSI, поэтому оно будет работать где угодно. Вероятно, существует менее подробное решение для Oracle, SQL Server или MySQL с использованием временных таблиц или табличных переменных. Поскольку СУБД не была указана, я не смог дать конкретный ответ для платформы и применил общий подход.

...