В SQL как отобразить значения двух строк и соотношение значений этих двух строк?

#sql #mariadb

#sql #mariadb

Вопрос:

У меня есть запрос (в MySQL, но это общий вопрос SQL), который выглядит следующим образом:

 SELECT 'Hits', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_HITS'

UNION

SELECT 'Inserts', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_INSERTS';  
  

Это приводит к следующему результату:

  --------- ---------------- 
| Hits    | variable_value |
 --------- ---------------- 
| Hits    | 8330           |
| Inserts | 7075           |
 --------- ---------------- 
  

То, что я пытаюсь получить, — это соотношение этих двух, которые находятся в одном и том же SQL. В основном результирующий набор выглядит следующим образом:

  --------- ---------------- 
| Hits    | variable_value |
 --------- ---------------- 
| Hits    | 8330           |
| Inserts | 7075           |
| H/I     | 1.177
 --------- ---------------- 
  

Как составить этот SQL? Я думаю, что может потребоваться объединение, но я не уверен, как получить значение двух строк для математики, используемой в SQL. Спасибо за любые указания!

Ответ №1:

Если вы можете принять их как три отдельных столбца, а не строки, вы можете сделать:

 select max(case when variable_name = 'QCACHE_HITS' then variable_value end) as hits,
       max(case when variable_name = 'QCACHE_INSERTS' then variable_value end) as inserts,
       (max(case when variable_name = 'QCACHE_HITS' then variable_value end) /,
        max(case when variable_name = 'QCACHE_INSERTS' then variable_value end)
       ) as ratio
from global_status ;
  

Возможно, даже проще отключить это:

 select h.hits,
       (case when h.hits = 'hits' then hits
             when h.hits = 'inserts' then inserts
             else ratio
        end) 
from (select max(case when variable_name = 'QCACHE_HITS' then variable_value end) as hits,
             max(case when variable_name = 'QCACHE_INSERTS' then variable_value end) as inserts,
             (max(case when variable_name = 'QCACHE_HITS' then variable_value end) /,
              max(case when variable_name = 'QCACHE_INSERTS' then variable_value end)
             ) as ratio
      from global_status
     ) s cross join
     (select 'hits' as hits union all
      select 'inserts' union all
      select 'h/i'
     ) x;
  

Это может показаться сложным, но в основном выполняется только одно сканирование global_status (хотя это может быть не так уж и важно для небольшой таблицы).

Комментарии:

1. идеальный ответ, даже я думал о том же самом, всего в нескольких строках, а не о том, что для этого требуется объединение как таковое

2. @GordonLinoff, спасибо. Супер. Это max() говорит мне то, что мне нужно было знать!

Ответ №2:

Я предположил, что ваш данный код работает, чтобы дать этот ответ.

 SELECT 'Hits', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_HITS'
UNION
SELECT 'Inserts', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_INSERTS'
UNION
SELECT 'H/I', (
(SELECT variable_value FROM global_status WHERE variable_name='QCACHE_HITS')
/
(SELECT variable_value FROM global_status WHERE variable_name = 'QCACHE_INSERTS')
) AS 'variable_value';
  

Комментарий в случае, если не работает. Удачи.

Комментарии:

1. Спасибо. Это работает! Мне очень нравится приведенная ниже идея G Linoff о преобразовании их в столбцы, но ваша более точна для конкретного заданного вопроса. Большое спасибо!

Ответ №3:

это будет работать:

 SELECT 'Hits', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_HITS'

UNION

SELECT 'Inserts', variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_INSERTS'

UNION

select 'H/I',(SELECT variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_HITS')/(SELECT variable_value 
FROM global_status 
WHERE variable_name = 'QCACHE_INSERTS') as variable_value
);
  

Комментарии:

1. Спасибо. В SQL есть какая-то ошибка, и без объяснения того, что происходит, я не смог ее устранить. Второй ответ здесь мне помогает. Большое спасибо!

Ответ №4:

Поскольку результаты вставки и попадания разные, просто объедините и разделите два отдельных подзапроса, как показано ниже, и получите o / p

Кроме того, соединение не требуется, потому что вам не нужен дополнительный столбец или etc, а дополнительные данные строки

    .... UNION
       Select 'H/I',(SELECT  variable_value 
      FROM global_status 
      WHERE variable_name = 
       'QCACHE_HITS')
       /
    (  SELECT variable_value 
     FROM global_status 
      WHERE variable_name = 
      'QCACHE_INSERTS')
  

Комментарии:

1. потому что объяснение ответа, который мы даем на то, что спрашивает OP, имеет значение