英文:
How to create an inline table from an existing table
问题
我有一个从数据库加载到 Qlik Sense 中的表格。
示例:
ID | 水果 | 蔬菜 | 数量 |
---|---|---|---|
1 | 苹果 | 5 | |
2 | 无花果 | 10 | |
3 | 胡萝卜 | 20 | |
4 | 橙子 | 12 | |
5 | 玉米 | 10 |
我需要创建一个筛选器,当选中时,显示所有水果/蔬菜记录以及来自其他关联表的记录。
筛选器应该类似于这样:
|水果_XXX|
|蔬菜_XXX |
希望有所帮助。
英文:
I have a table in qlik Sense loaded from the database.
Example:
ID | FRUIT | VEG | COUNT |
---|---|---|---|
1 | Apple | 5 | |
2 | Figs | 10 | |
3 | Carrots | 20 | |
4 | Oranges | 12 | |
5 | Corn | 10 |
From this I need to make a filter that will display all the Fruit/Veg records along with records from other joined tables, when selected.
The filter needs to be something like this :
|FRUIT_XXX|
|VEG_XXX |
Any help will be appreciated.
答案1
得分: 1
不确定是否能够实现动态。通常,我会通过创建一个新字段,将两个字段的值合并到一个字段中来解决这个问题。
这将创建一个新表格(Combined
),它将与主表格通过 ID
字段关联:
新的 Combined
字段将具有以下值:
而用户界面将如下所示:
另外,如果需要进一步处理,您可以将 Combined
表格与 RawData
表格连接起来。这样,Combined
字段将成为 RawData
表格的一部分。要实现这一点,只需稍微扩展脚本:
join (RawData)
Load * Resident Combined;
Drop Table Combined;
英文:
Not sure if its possible to be dynamic. Usually I solve these by creating a new field that combines the values from both fields into one field
RawData:
Load * Inline [
ID , FRUIT ,VEG , COUNT
1 , Apple , , 5
2 , Figs , , 10
3 , ,Carrots , 20
4 , Oranges , , 12
5 , ,Corn , 10
];
Combined:
Load
ID,
'FRUIT_' & FRUIT as Combined
Resident
RawData
Where
FRUIT <> ''
;
Concatenate
Load
ID,
'VEG_' & VEG as Combined
Resident
RawData
Where
VEG <> ''
;
This will create new table (Combined
) which will be linked to the main table by ID
field:
The new Combined
field will have the values like this:
And the UI:
P.S. If further processing is needed you can join the Combined
table to the RawData
table. This way the Combined
field will become part of the RawData
table. To achieve this just extend the script a bit:
join (RawData)
Load * Resident Combined;
Drop Table Combined;
答案2
得分: 0
在QlikSense中,我不知道如何操作,但在SQL中,可以这样实现:
SELECT
ID,
CASE WHEN FRUIT IS NULL THEN VEG ELSE FRUIT END as FruitOrVeg,
COUNT
FROM tablename
英文:
I do not know how to do it in qlicksense, but in SQL it's like this:
SELECT
ID
CASE WHEN FRUIT IS NULL THEN VEG ELSE FRUIT END as FruitOrVeg,
COUNT
FROM tablename
答案3
得分: 0
要在动态情况下执行此操作,您应该使用 CrossTable()
函数。这将允许您将表格旋转,以使 n 列“枢轴”为仅两列,一列用于列名,另一列用于列值。
以下是用于执行此操作的脚本:
// 步骤 1
[原始数据]:
Load * Inline [
ID , 水果 , 蔬菜 , 数量
1 , 苹果 , , 5
2 , 无花果 , , 10
3 , , 胡萝卜 , 20
4 , 橙子 , , 12
5 , , 玉米 , 10
];
// 步骤 2
Rename Field [ID] to [ID 旧];
Rename Field [COUNT] to [COUNT 旧];
[重新排序数据]:
NoConcatenate Load
[ID 旧] as [ID]
, [COUNT 旧] as [COUNT]
, *
Resident [原始数据];
Drop Table [原始数据];
Drop Fields [ID 旧], [COUNT 旧];
// 步骤 3
[动态数据]:
CrossTable ([类型], [项目], 2)
Load *
Resident [重新排序数据];
Drop Table [重新排序数据];
// 步骤 4
[合并数据]:
Load
[ID]
, [COUNT]
, [类型]
, [项目]
, [类型] & '_' & [项目] as [完整项目]
Resident [动态数据]
Where Not IsNull(EmptyIsNull([项目]))
;
Drop Table [动态数据];
以下是脚本的工作原理:
步骤 1.
:从 Oracle 数据库加载数据。您可以根据需要添加新的食品类别作为列。
步骤 2.
:我们假设我们可以动态加载新的食品类别,但不是其他类型的新列,比如“价格”之类的。为了使 Qlik 中的动态部分起作用,我们将在下一步中使用 CrossTable()
函数。该函数要求字段按“常规”字段的顺序排列,这些字段保持不变,然后是“食品类别”字段,这些字段将被枢轴。因此,我们将确保我们的两个“常规”列首先排序。为了实现这一点,我们只需使用 Rename Field
关键字将它们临时重命名,然后在 [重新排序数据]
表中首先加载它们,确保将它们别名回原始字段名。这使我们可以使用星号 *
,它将在这两个字段之后加载所有其他字段。这样,您可以在将来加载尽可能多的食品类别字段 - 我们将始终在“常规”字段之后加载它们。
步骤 3.
:在这里,我们使用 CrossTable ([类型], [项目], 2)
函数,它的含义是“在前两个字段之后,将剩余字段枢轴,使列名(“水果”,“蔬菜”)放入新生成的 [类型]
字段中,将所有列值(“苹果”,“无花果”,“胡萝卜”,“玉米”)放入另一个新生成的字段中,名为 [项目]
。
步骤 4.
:最后,我们可以将我们的 [类型]
和 [项目]
字段组合成一个新的 [完整项目]
字段,以获得您想要的结果。我们使用 &
运算符将字段值连接在一起。我们的 Where
子句 Where Not IsNull(EmptyIsNull([项目]))
的含义是“返回那些 [项目]
不为 null
的记录,而在这种情况下,空值将被视为 null
。”
这是您的结果应该是什么样子的:
然后,如果您想在将来添加新的食品类别字段,比如乳制品,您的加载脚本是完全动态的,将正确处理这些新记录和列:
[原始数据 增加乳制品]:
Load * Inline [
ID , 水果 , 蔬菜 , 乳制品 , 数量
1 , 苹果 , , , 5
2 , 无花果 , , , 10
3 , , 胡萝卜 , , 20
4 , 橙子 , , , 12
5 , , 玉米 , , 10
6 , , , 牛奶 , 31
7 , , , 奶酪 , 19
8 , , , 酸奶 , 13
];
此外,如果您仍然希望保留原始的 [水果]
和 [蔬菜]
字段,您可以删除或注释掉我的示例脚本中的 Drop Table [重新排序数据];
行。
英文:
To do this dynamically, you should use the CrossTable()
function. This will allow you to pivot your table such that n number of columns "pivot" into just 2 columns, one for the column name and one for the column value.
Here's the script you could use to achieve this:
// STEP 1
[Original]:
Load * Inline [
ID , FRUIT , VEG , COUNT
1 , Apple , , 5
2 , Figs , , 10
3 , , Carrots , 20
4 , Oranges , , 12
5 , , Corn , 10
];
// STEP 2.
Rename Field [ID] to [ID old];
Rename Field [COUNT] to [COUNT old];
[Reordered]:
NoConcatenate Load
[ID old] as [ID]
, [COUNT old] as [COUNT]
, *
Resident [Original];
Drop Table [Original];
Drop Fields [ID old], [COUNT old];
// STEP 3.
[Dynamic]:
CrossTable ([Type], [Item], 2)
Load *
Resident [Reordered];
Drop Table [Reordered];
// STEP 4.
[Combined]:
Load
[ID]
, [COUNT]
, [Type]
, [Item]
, [Type] & '_' & [Item] as [Full Item]
Resident [Dynamic]
Where Not IsNull(EmptyIsNull([Item]))
;
Drop Table [Dynamic];
Here's how it works:
STEP 1.
: Load the data from Oracle DB. You can add new food categories as columns as needed.
STEP 2.
: We are assuming that we may dynamically load in new food categories, but not other types of new columns like "Price" or things like that. In order to get the dynamic part to work in Qlik, we will use the CrossTable()
function in the next step. That function requires fields to be in order of "regular" fields that stay put, followed by "food category" fields that will be pivoted. As such, we are going to ensure that our two "regular" columns are ordered first. To achieve this, we simply rename them temporarily using the Rename Field
keywords and then loading them first in our [Reordered]
table, making sure that we alias them back to their original field names. This allows us to use the asterisk *
, which will load all other fields after those ones. This makes it so that you can load as many food category fields as you want in the future -- we'll always load the them after our "regular" fields.
STEP 3.
: Here we use the CrossTable ([Type], [Item], 2)
function, which is saying "after the first 2 fields, pivot the remaining fields such that the column names ("FRUIT", "VEG") go into a newly generated [Type]
field and all of the column values ("Apple", "Figs", "Carrots", "Corn") go into another newly generated field called [Item]
.
STEP 4.
: Finally, we can combine our [Type]
and [Item]
fields into a new [Full Item]
field to get the result you desire. We use the ampersand &
operator to concatenate the fields values together. Our Where
clause, Where Not IsNull(EmptyIsNull([Item]))
, is saying "return records where [Item]
is not null
, and empty values are to be considered null
in this case."
This is what your result should look like:
Then if you wanted to add new food category fields in the future, like dairy, your load script is fully dynamic and will correctly handle those new records and columns:
[Original Plus Dairy]:
Load * Inline [
ID , FRUIT , VEG , DAIRY , COUNT
1 , Apple , , , 5
2 , Figs , , , 10
3 , , Carrots , , 20
4 , Oranges , , , 12
5 , , Corn , , 10
6 , , , Milk , 31
7 , , , Cheese , 19
8 , , , Yogurt , 13
];
Also, if you still want to keep your original [FRUIT]
and [VEG]
fields, you can just delete or comment out the Drop Table [Reordered];
line from my example script above.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论