Pergunta

Basicamente, tenho 7 instruções selecionadas que preciso para obter os resultados em colunas separadas. Normalmente, eu usaria um Crosstab para isso, mas preciso de uma maneira rápida eficiente de fazer isso, pois há mais de 7 bilhões de linhas na tabela. Estou usando o sistema de banco de dados Vertica. Abaixo está um exemplo das minhas declarações:

SELECT COUNT(user_id) AS '20100101' FROM event_log_facts WHERE date_dim_id=20100101
SELECT COUNT(user_id) AS '20100102' FROM event_log_facts WHERE date_dim_id=20100102
SELECT COUNT(user_id) AS '20100103' FROM event_log_facts WHERE date_dim_id=20100103
SELECT COUNT(user_id) AS '20100104' FROM event_log_facts WHERE date_dim_id=20100104
SELECT COUNT(user_id) AS '20100105' FROM event_log_facts WHERE date_dim_id=20100105
SELECT COUNT(user_id) AS '20100106' FROM event_log_facts WHERE date_dim_id=20100106
SELECT COUNT(user_id) AS '20100107' FROM event_log_facts WHERE date_dim_id=20100107

deve devolver algo como:

20100101 | 20100102 | 20100103 | 20100104 | 20100105 | 20100106 | 20100107
1234     | 1234     | 36564    | 45465    | 356754   | 3455     | 4556675
Foi útil?

Solução

Você pode usar uma série de consultas unidas. Meio feio, mas deve funcionar

SELECT  
  COUNT(user_id) AS '20100101'  
 ,NULL AS '20100102'  
 ,NULL AS '20100103'  
 ,NULL AS '20100104'  
 ,NULL AS '20100105'  
FROM  
  event_log_facts  
WHERE  
  date_dim_id=20100101  
UNION  
SELECT  
  NULL AS '20100101'  
 ,COUNT(user_id) AS '20100102'  
 ,NULL AS '20100103'  
 ,NULL AS '20100104'  
 ,NULL AS '20100105'  
FROM   
  event_log_facts  
WHERE  
  date_dim_id=20100102  
UNION  
SELECT  
  NULL AS '20100101'  
 ,NULL AS '20100102'  
 ,COUNT(user_id) AS '20100103'  
 ,NULL AS '20100104'  
 ,NULL AS '20100105'  
FROM  
  event_log_facts  
WHERE  
  date_dim_id=20100103  

Etc ...

Outras dicas

Enrole -os entre parênteses, adicione vírgulas e selecione -os :)

SELECT
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100101) AS '20100101',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100102) AS '20100102',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100103) AS '20100103',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100104) AS '20100104',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100105) AS '20100105',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100106) AS '20100106',
(SELECT COUNT(user_id) FROM event_log_facts WHERE date_dim_id=20100107) AS '20100107'

Ou você pode fazer uma função escalar que toma como parâmetro o date_dim_id e retorna o resultado desejado e chamá -lo várias vezes .. ( Se o seu sistema de banco de dados suportar funções escalares )

SELECT
COUNT(date_dim=20100101 OR NULL) AS '20100101',
COUNT(date_dim=20100102 OR NULL) AS '20100102',
...
FROM event_log_facts

Bem, considere o uso da tabela pivô. É mais olho -saco :)

Em primeiro lugar, união seus resultados, do que gire!

Aqui está seu exemplo, e aqui está The Sqlfiddle -> http://sqlfiddle.com/#!6/d41d8/6440

SELECT PivT.* 
FROM
(
  SELECT 10 As Quantity, '20100101' AS DateDim
  UNION
  SELECT 21 , '20100102' 
  UNION
  SELECT 3 , '20100103' 
  UNION
  SELECT 41 , '20100104' 
  UNION
  SELECT 50 , '20100105' 
  UNION
  SELECT 26 , '20100106' 
  UNION
  SELECT 78 , '20100107' 
) T
 PIVOT (avg(Quantity) for DateDim in ([20100101],
                         [20100102],
                         [20100103],
                         [20100104],
                         [20100105],
                         [20100106],
                         [20100107])
) As PivT
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top