2015-05-22 5 views
1

Я новичок как в Cassandra (2.0), так и в QlikView (11).
У меня есть два пространства ключей (таблицы) с большим количеством данных в Cassandra, и я хочу загрузить их в QlikView.
Поскольку я не могу загрузить весь набор, необходима фильтрация.Загрузите соединительные столы из Cassandra в QlikView с DataSatx ODBC

// In QlikView's edit script 
ODBC CONNECT TO [DataStax Cassandra ODBC DSN64]; 
LOAD idsession, 
logintime, 
"h_id" as hid; 
SQL SELECT * 
FROM Cassandra.test.sessions 
WHERE logintime > '2015-06-09' 
ALLOW FILTERING; 

LOAD idhost, 
site; 
SQL SELECT * 
FROM Cassandra.test.hosts 
WHERE idhost in hid; 

Второй запрос не работает, ошибка из QlikView линии 3:16 жизнеспособной альтернативы на входе «спрятался».

Мой вопрос: можно ли получить h_ids из первого запроса и собрать только соответствующие объекты из второй таблицы?

Я предполагаю, что вы не можете использовать Exis в DataSyntax ODBC, который может помочь. DataStax doc

Это может быть сделано с помощью внешней программы, как (C#), но я действительно хочу сделать это в файл сценария QlikView в:

// Not complete code 
query = select * from sessions where loginTime > '2015-06-09'; 
foreach (var id in query) { 
query2 = "select * from hosts where idhost = " + i; 
} 

EDIT
Эту проблему можно решить при загрузке XML-файлов:

TableA: 
LOAD id, 
itema 
FROM 
[C:\test1data.xlsx] 
(ooxml, embedded labels); 

TableB: 
LOAD idb, 
itemb, 
ida 
FROM 
[C:\test2data.xlsx] 
(ooxml, embedded labels) where(Exists (id,ida)); 

EDIT2
Кроме большой ответ от @i_saw_drones - это еще одно решение - перебрать идентификаторы.

For i = 1 to NoOfRows('Sessions') 
Let cur_id = Peek('hid',i - 1,'Sessions'); 
LOAD 
    idhost, 
    site; 
    SQL SELECT * 
    FROM Cassandra.test.hosts 
    WHERE idhost = $(cur_id); 
NEXT i 

Тем не менее, представление было не великим. Для загрузки около 300 К линий из Кассандры потребовалось около 30 минут. Те же запросы были протестированы в программе C# с разъемом, и потребовалось 9 секунд. Но это был только запрос. Затем вы должны записать его в XML, а затем загрузить в QlikView.

ответ

2

Причина, по которой второй запрос терпит неудачу, заключается в том, что в предложении WHERE ожидается, что список строк будет выглядеть буквально. Например:

LOAD 
    idhost, 
    site; 
SQL SELECT * 
FROM Cassandra.test.hosts 
WHERE idhost in ('ID1', 'ID2', 'ID3', 'ID4'); 

hid поле, возвращенное первого запроса представляет собой список QlikView, и как таковой не может быть немедленно приводится к строке. Мы должны сделать немного больше скриптов, чтобы получить список значений из первого запроса в литеральной форме, а затем добавить это ко второму запросу как часть предложения WHERE. Самый простой способ сделать это - объединить все ваши hid s в строку, а затем использовать эту строку как часть вашего предложения WHERE IN.

ODBC CONNECT TO [DataStax Cassandra ODBC DSN64]; 

MyData: 
LOAD 
    idsession, 
    logintime, 
    "h_id" as hid; 
SQL SELECT * 
FROM Cassandra.test.sessions 
WHERE logintime > '2015-06-09' 
ALLOW FILTERING; 

hid_entries: 
LOAD 
    chr(39) & hids & chr(39) as hids; 
LOAD 
    concat(hid, chr(39) & ',' & chr(39)) as hids; 
LOAD DISTINCT 
    hid 
RESIDENT MyData; 

LET hid_values = '(' & peek('hids',0,'hid_entries') & ')'; 

DROP TABLE hid_entries; 

LOAD 
    idhost, 
    site; 
SQL SELECT * 
FROM Cassandra.test.hosts 
WHERE idhost in $(hid_values); 
+0

Это работает. Спасибо! – Fredrik

+0

Когда я применяю это решение к таблице с большим количеством данных, он плохо масштабируется. У вас есть советы по другим решениям, которые могут масштабироваться лучше? – Fredrik

+0

Если у вас много дубликатов в поле 'hid', то добавление' DISTINCT' в таблицу 'hid_entries' загружает только уникальные значения, которые могут повысить производительность. Поскольку это операторы SQL SELECT, вы можете использовать только SQL, совместимый с целевым провайдером, поэтому вы не сможете использовать специальные функции QV, такие как 'exist', если вы не извлечете весь файл' Cassandra.test.hosts' стол сначала. –

Смежные вопросы