Im using Entity Framework 6.
Given the following models:
MyType (Id+Language are keys)
- Id
- Language // will be represented by values like "en", "no", "dk", "de"
- Label
MyValue (Id+SomeOtherEntityId+Language are keys)
- Id
- SomeOtherEntityId
- Language
- Value
I'd like the Id column in MyTypes to auto increment whenever a new language is given for that Id, if that makes sense.
Example:
context.MyTypes.Add(new MyType { Label = "Label", Language = "no" });
context.MyTypes.Add(new MyType { Label = "Label", Language = "da" });
context.MyTypes.Add(new MyType { Label = "Label", Language = "nl" });
This gives me a database that looks like the following:
| Id | Language | Label |
|----|----------|-------|
| 1 | no | Label |
| 2 | da | Label |
| 3 | nl | Label |
While what I really want is this:
| Id | Language | Label |
|----|----------|--------|
| 1 | no | Label |
| 1 | da | Label |
| 1 | nl | Label |
| 2 | no | Label2 |
| 2 | da | Label2 |
| 2 | nl | Label2 |
I have currently set my ID column as an Identity, thus making it auto incrementing.
Is it possible, from a database perspective, to configure this to be auto incrementing, depending on the Language column?
Is this configurable via EntityFramework?
I guess an alternative would be to have a separate Type-table with just an ID, and then link the Labels for different languages to this. However, I was hoping to avoid that simply because this structure is so simple, and having another table just for the ID's sake seems to me to just add some unnecessary complexity.
Another alternative could be to control this from code (when inserting new MyTypes, get the correct ID first and then add the rest).
Is there any best practices concerning this type of problem?
what you try to do can't be done, in my knowledge. (identity is one distinct value by row)
two tables seems right to me:
tableHead(Id, Code, Blabla)
tableTrans(Id, ExtId, Language, Value), with ExtId as a FK
or
tableTrans(ExtId, Language, Value) with a composite Key comprisong the FK
then you get you translation by a Code value and a Language value and get readable code.
Related
I am confused about the logic that exists behind the showing and hiding of rows in charts of QlikView/QLik Sense. Here is what I thought was the case:
If, for some row, the value of a dimension is NULL, and for that dimension "Supress NULL" is on (QV) or "Include NULLs" is off(QS), then the row is not shown.
If, for some row, all its expressions/measures are zero or NULL, and the object-level setting "Supress Zero Values" is on (QV), or "Include Zero Values" is off (QS), then the row is not shown.
The rest of the rows are shown.
However, I get a confusing example of a measure which causes rows to disappear even though I have suppress zero values off/ inlude zero values on. Here is a small script of some sample customers and their consultation:
customer:
LOAD * INLINE [
custcode,descr
C1,pan1
C2,pan2
C3,pan3
];
consultation:
LOAD * INLINE [
custcode,grp,val,x
C2,eye,sth1,1
C2,age,20,1
C3,legs,sth2,1
C3,skin,sth5,1
C3,age,20,1
C3,age,30,1
];
As you can see, custcode C1 has no consultation lines. I proceed to create a straight table with custcode as dimension and sum(x) as measure. Here is what I get:
+----------+--------+
| custcode | sum(x) |
+----------+--------+
| C1 | 0 |
| C2 | 2 |
| C3 | 4 |
+----------+--------+
Everything fine until now. Sure enough I haven't supressed zero values: If I did, the C1 row would get removed. Also, let's note that no aggr is needed for whatever reason.
Now, let's add a set analysis to that measure to only sum x for grp='age':
sum({<grp={'age'}>}x)
This hides row C1 from sight:
+----------+-----------------------+
| custcode | sum({<grp={'age'}>}x) |
+----------+-----------------------+
| C2 | 1 |
| C3 | 2 |
+----------+-----------------------+
Question 1: Why does set analysis hide the row in this case?
Adding an additional measure with a value of 1 changes nothing. We can be sure this has nothing to do with zero values settings.
Now, let us add this measure:
aggr(min(0),[custcode])
The row got back, even though the new measure is NULL :
+----------+-----------------------+-------------------------+
| custcode | sum({<grp={'age'}>}x) | aggr(min(0),[custcode]) |
+----------+-----------------------+-------------------------+
| C1 | 0 | - |
| C2 | 1 | - |
| C3 | 2 | - |
+----------+-----------------------+-------------------------+
Now, about aggr, here are two strong reasons why I think it should not be neccessary:
If the set analysis measure was wrong and needed to include aggr in some way, this would still be no reason for the engine to hide the rows - it would just return a NULL for having an invalid formula. Also, this measure actually works correct, as we can see
custcode is the field which creates the association between the two tables. But this doesn't seem to be the cause for it to unhide rows; actually, I get the same even with aggr(min(0),[]):
+----------+-----------------------+-----------------+
| custcode | sum({<grp={'age'}>}x) | aggr(min(0),[]) |
+----------+-----------------------+-----------------+
| C1 | 0 | - |
| C2 | 1 | - |
| C3 | 2 | - |
+----------+-----------------------+-----------------+
Question 2: Why does this strange aggr measure unhide the row?
Question 1:
When you only have the one expression and add the set analysis it is like telling Qlik to select the set value.
So picture 1 no selections
picture 2 with the selection
So it's not that the answer is a null, it is that the associative engine has reduced that data out of the data set based on the selection / set rule.
The aggr() should definitely not be necessary there. The dimentionality of the chart will take care of the aggregation across the dimension. aggr() is only needed when you want to use an aggregation that is not controlled by the dimensions.
I do not understand what your aggr(min(0),[]) is trying to achieve and I don;'t get the same result as your table. The expression is just creating nulls because it is can't evaluate
If you want to see all members of the dimension you should tick "Show all values" on the dimensions tab rather than trying to change the expressions
This is a similar question to the one I posted last week.
I have an internal table based off of a dictionary structure with a format similar to the following:
+---------+--------+---------+--------+---------+--------+-----+
| column1 | delim1 | column3 | delim2 | column5 | delim3 | ... |
+---------+--------+---------+--------+---------+--------+-----+
| value1 | | | value 1 | | | value 1 | | | ... |
| value2 | | | value 2 | | | value 2 | | | ... |
| value3 | | | value 3 | | | value 3 | | | ... |
+---------+--------+---------+--------+---------+--------+-----+
The delim* columns are all of type delim, and the typing of the non-delimiter columns are irrelevant (assuming none of them are also type delim).
The data in this table is obtained in a single statement:
SELECT * FROM <table_name> INTO CORRESPONDING FIELDS OF TABLE <internal_table_name>.
Thus, I have a completely full table except for the delimiter values, which are determined by user input on the selection screen (that is, we cannot rely on them always being ,, or any other common delimiter).
I'd like to find a way to dynamically set all of the values of type delim to some input for every row.
Obviously I could just hardcode the delimiter names and loop over the table setting all of them, but that's not dynamic. Unfortunately I can't bank on a simple API.
What I've tried (this doesn't work, and it's such a bad technique that I felt dirty just writing it):
DATA lt_fields TYPE TABLE OF rollname.
SELECT fieldname FROM dd03l
INTO TABLE lt_fields
WHERE tabname = '<table_name>'
AND as4local = 'A'
AND rollname = 'DELIM'.
LOOP AT lt_output ASSIGNING FIELD-SYMBOL(<fs>).
LOOP AT lt_fields ASSIGNING FIELD-SYMBOL(<fs2>).
<fs>-<fs2> = '|'.
ENDLOOP.
ENDLOOP.
Once again, I'm not set in my ways and would switch to another approach altogether if I believe it's better.
Although I still believe you're barking up the wrong tree with the entire approach, You have been pointed in the right direction both here and in the previous question
ASSIGN COMPONENT <fs2> OF STRUCTURE <fs> TO FIELD-SYMBOL(<fs3>). " might just as well continue with the write-only naming conventions
IF sy-subrc = 0.
<fs3> = '|'.
ENDIF.
I have three tables with data like this:
An item table that contains basic info per item. Each item has one 'template' that determines a set of meta data for items with that template.
id | name | template_id
--------------------------
1 | Thing1 | t1
2 | Thing2 | t2
A template_fields table that contains a row for each type of meta data that could be associated with an item with particular template. It looks something like the table below. Here there are two templates, one with two fields and one with a single field. (The number of fields can vary per template.)
id | key | order
--------------------
t1 | color | 1
t1 | size | 2
t2 | year | 1
Finally, there is a meta_data table that contains the actual values associated with the template fields for each item:
item_id | template_id | key | value
--------------------------------------
1 | t1 | color | Red
1 | t1 | size | 2
2 | t2 | year | 2014
Now, in my application I want to have a per-template view of this data so that if I want to see items of template a particular template each row in the result set contains a column for each field in the corresponding template. For example, items in template t1 would look like this:
item_id | name | color | size
--------------------------------
1 | Thing1 | Red | 2
Similarly for items in template t2
item_id | name | year
------------------------
1 | Thing2 | 2014
Is there a way to do this in a single SQL query? (Keep in mind that I do not know the number of fields in a template until runtime. I am also not concerned with having a view that contains fields from items with different templates; one template at a time.)
My best whack at a solution so far is something like the pseudo code below, but please let me know if you think there is a better way (including a better table structure) to accomplish what I want.
fields = SELECT template_fields.key, meta_data.value FROM template_fields
JOIN meta_data ON
meta_data.template_id = template_fields.id
AND meta_data.key = template_fields.key
WHERE meta_data.item_id IN (SELECT id FROM item WHERE template='t1')
ORDER BY meta_data.item_id, template_fields.order
items = SELECT * FROM item WHERE template='t1'
i = 0
for item in items:
while fields[i].item_id = item.id:
item[fields[i].key] = fields[i].value
i += 1
Here's an SQL Fiddle link to play with
I have two tables, like this:
t_Normal
----------------------------------------------
FieldKey | FieldLabel | FieldValue
----------------------------------------------
greet_hw | Hello, world! | HELLOWORLD
----------------------------------------------
greet_ws | What's shakin? | WHATISSHAKING
----------------------------------------------
greet_hh | How's it hangin?| HOWDOESITHANG
----------------------------------------------
t_Override
------------------------------------------------------------
FieldKey | FieldLabel | FieldValue | FieldStatus
------------------------------------------------------------
greet_ws | What's shakin? | WHATISSHAKING | Retired
------------------------------------------------------------
greet_s | Sup!?!?? | SUPELEVEN | Active
------------------------------------------------------------
greet_hh | How swings it? | HOWDOESITHANG | Active
------------------------------------------------------------
Can I join them in a view to get this:
v_FieldMaster
---------------------------------------------
FieldKey | FieldLabel | FieldValue
---------------------------------------------
greet_hw | Hello, world! | HELLOWORLD
---------------------------------------------
greet_s | Sup!?!?? | SUPELEVEN
---------------------------------------------
greet_hh | How swings it? | HOWDOESITHANG
---------------------------------------------
So it's joined to produce v_FieldMaster like this:
Any totally different table rows (where comparison is made based on a combination of FieldKey and FieldValue) are included. E.g. Hello, world! only appears in t_Normal, and Sup!?!?? only appears in t_Override.
Any rows that match based on Name and Value take the t_Override table's Label field. E.g. How swings it? instead of How's it hangin?
Any rows that appear in both (or just t_Override) , but are set as Status=Retired in t_Override, do not appear. E.g. What's shakin'? doesn't appear.
Quickest way to combine two identical structured tables without duplicate entries has got me part of the way there, but I haven't yet figured out how to combine that technique with a where clause matching on t_Override.FieldStatus. Any suggestions very welcome!
Do a full join, but only select the rows where there is either no override or the override is 'Active'. Coalesce each field to prioritize the override values if they are there.
SELECT
COALESCE(o.FieldKey ,n.FieldKey ) AS FieldKey ,
COALESCE(o.FieldLabel ,n.FieldLabel ) AS FieldLabel ,
COALESCE(o.FieldStatus,n.FieldStatus) AS FieldStatus
FROM t_Normal n
FULL JOIN t_Override o ON (o.FieldKey = n.FieldKey)
WHERE (o.FieldKey IS NULL OR o.FieldStatus = 'Active')
For query data like this:
+-------+---------+
| Name | Details |
| JEFF | TEST1 |
| JEFF | TEST2 |
| JEFF | TEST3 |
| BOB | TEST1 |
| BOB | TEST2 |
+-------+---------+
How do I query so that a numerical sequence (1,2,3...) can be added that resets back to 1 each time the name changes (ie from JEFF to BOB)?
Is it possible to use the DCOUNT function?
What I have so far is (it doesn't sequence correctly):
Number: (SELECT COUNT(*) FROM [dQuery]
WHERE [dQuery].[Name] = [dQuery].[Name]
AND [dQuery].[sequence] >= [dQuery].[sequence])
UPDATE1:
The correct query is:
SELECT [dQuery].Name, [dQuery].[sequence], (select count([dQuery].Name) + 1
from [dQuery] as dupe where
dupe.[sequence]< [dQuery].[sequence] and dupe.name = [dQuery].name
) AS [Corrected Sequence]
FROM [dQuery]
WHERE ((([dQuery].Name)="jeff"))
ORDER BY [dQuery].Name, [dQuery].[sequence];
Take a look here. I think the author has solved some very similar issues.
If you like to add a serial number in your report dynamically than, create a report for the specific table and open the report in design view. Then, add a text box in the left side of the the data row and give "=1" (with out colon) to its Control Source property # "Data" tab. And change "No" to "Over Group" of its "running sum" property # "Data" tab. At the run time that text field will show data in sequence like 1, 2, 3 in every row.
Thanks