Re: [sqlite] Db design question (so. like a tree)

2009-06-05 Thread Francis GAYREL
I am not familiar with breeding business.
My suggestion comes from a very different problem that i solved recently.
The challenge was to describe a tree and  to find the path to the root 
starting from any leaf or intermediate node.
How to do?
1) The entity supported by  the node shall support at least one relative 
precedence criterion  which depends on the nature of the entity.
Then we can specify a Node_Table(Node Primary 
Key,,PrecedenceCriterion)
2) Populate the Node_Table (at least 2 linkable nodes at starting time)
3) Complete the links using a selection filter mainly based on 
precedence (we assume that the user has the expertise to pick the right 
choice)
4) Repeat 2) and 3) as far as necessary
If only one-to-one links are required they can be included in the 
Node_Table model.
If one-to-several links are necessary a separate 
Link_Table(LinkType,OwnerNode,LinkedNode) is recommended. (for example 
Link  types  may be Father,Mother,Clone)

John Machin a écrit :
> On 5/06/2009 5:27 PM, Francis GAYREL wrote:
>   
>> To build a consistent oriented tree we need to associate to the nodes a 
>> ranking property such as the birthdate (or any precedence criterion).
>> Therefore the ancestor of  someone  is to be selected among  older ones.
>> 
>
> "Ancestor" is a *derived* relationship, not something you'd wish to 
> store in the database, and is quite irrelevant at data-entry time. Don't 
> you mean "parent"?
>
> Let me get this straight: the user is entering the details of animal X 
> who was born yesterday and has to input somehow the identity of the 
> mother and of the father.
>
>   
>> To make the ancestor allocation more easy  the ancestor's list may be 
>> filtered on birthdate credibility.
>> 
>
> So your plot is, (e.g. for the father) to show a list of all male 
> animals who are in some credible-parenthood age range on (say) a 
> drop-down list, and the user selects one, hopefully not at random. Is 
> that right?
>
> I would imagine in a planned targeted organised animal breeding program 
> that the mother-to-be and father-to-be are recorded at the time of 
> impregnation, and the identities are established from ear-tags, embedded 
> chips, photographs, etc and the credible-parenthood test is applied then 
> [note: test, NOT input selection method] and all of the above is 
> confirmed at birth.
>
>   
>> The ranking property eliminates the circular link concern.
>> 
>
> Indeed, but you have to use it properly to eliminate other data 
> integrity concerns :-)
>
> HTH,
>
> John
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
>
>   

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] Db design question (so. like a tree)

2009-06-05 Thread Francis GAYREL
To build a consistent oriented tree we need to associate to the nodes a 
ranking property such as the birthdate (or any precedence criterion).
Therefore the ancestor of  someone  is to be selected among  older ones.
To make the ancestor allocation more easy  the ancestor's list may be 
filtered on birthdate credibility.
The ranking property eliminates the circular link concern.


Jan a écrit :
> Hi Mark,
>
> I think that wont work:
>
> Scenario: A calf is born from a mother within your flock but from a 
> father outside. The father appears for the first time and you are not 
> able to gather information on his father (or grand-grand father). 
> Therefore his father is NULL. But later you get the information on his 
> father and add it to the animal list: The id of the fathers father is 
> then greater then the id of his grandchild (the calf).
> I could start the id initially with 10 to allocate <10 ids in 
> theses cases, but I am unsure if this is a good way to start.
>
> Mark Hamburg schrieb:
>   
>> One of the questions that I believe was raised but not answered on  
>> this thread was how to make sure that you don't have circular  
>> relationships particularly given that SQLite isn't good at scanning  
>> the tree. If you can control the id's then simply require that the id  
>> of the child be greater than the id's of the parents.
>>
>> Mark
>>
>> ___
>> sqlite-users mailing list
>> sqlite-users@sqlite.org
>> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>>
>> 
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
>
>   

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to use PRIMARY KEY AUTOINCREMENTwhenmodellingweakentities?

2008-09-06 Thread Francis GAYREL
Can I suggest another way that I adopted a long time ago to solve this 
kind of issue?
Forget the autoincrement  function included in your RDBM and use a 
customized one more or less similar to the one I developped in my ZQLib 
(adapted from ZEOSDBO) for Delphi (previously I did the same thing with 
MS-Access):

{==Primary key management
Primary Key is a shaped string  which consists of prefix+serial number
PkSize is the width of the serial number
Const  NullString='';
M_ZQLite is a module hosting various ZEOSDBO objects, especially ZQread 
which is a TZReadOnlyQuery
PrimKeyZero, PrimKeyMax and LastPrimKey may be private.
}

Function PrimKeyZero(PkSize:integer):string; //lowest serial number value
var i:integer;
begin
  Result:=NullString;
  For i:=1 to PkSize Do Result:=Result+'0';
end;

Function PrimKeyMax(PkSize:integer):string; //highest serial number value
var i:integer;
begin
  Result:=NullString;
  For i:=1 to PkSize Do Result:=Result+'9';
end;

Function LastPrimKey(Table, PkField,Prefix: String;var 
PkVal:string):boolean;
begin
  Result:=False;
  With M_ZQLite Do
  BEGIN
  ZQread.SQL.Clear;
  ZQread.SQL.Add('SELECT MAX('+PkField +') FROM '+ Table +
 ' WHERE '+ PkField + ' LIKE '+QuotedStr(Prefix+'%')+';');
  Try
ZQread.Open;
if ZQread.IsEmpty
Then
PkVal:=NullString
else PkVal:=ZQread.Fields[0].AsString;
Result:=True;
  Finally
ZQread.Close;
  End;
  END;
End;

Function NextPrimKey(Table, PkField,Prefix: String;PkSize:integer;var 
PkNext:string):boolean;
var
  LastK: String;
  N:longint;
  code:integer;
Begin
  Result:=False;
  If not LastPrimKey(Table, PkField, Prefix,LastK) Then exit;
  If LastK=NullString
  Then Begin
   PkNext:=Prefix + PrimKeyZero(PkSize);
   Result:=True;
   Exit;
   End
  Else LastK := Copy(LastK,Length(Prefix)+1, PkSize);
  If LastK =PrimKeyMax(PkSize)
  Then begin
   ShowMessage(Glob_PrimKeyOver);
   exit;
   End;
  Val(LastK,N,code);
  PkNext:= Prefix + Format('%*.*d',[PkSize,PkSize,N+1]);
  Result:=True;
End;

Assuming that the Civil Work DB has to manage les than100 buildings, 
each one containing less than 1 rooms.

When adding a building:
if NextPrimKey(T_Building, 'BuildingID',NullString,2,NextBuilding)
then ZQrun('INSERT INTO T_Building(BuildingID,.) 
VALUES('+QuotedStr(NextBuilding)+',;);');

When adding a room:
if NextPrimKey(T_Room, 'RoomID',CurrentBuilding,4,NextRoom)
then ZQrun('INSERT INTO T_Room(RoomID,.) 
VALUES('+QuotedStr(NextRoom)+',;);');

I would point out that this approach permits  meaningfull  keys which 
offer a lot of possibilities.


Igor Tandetnik a écrit :
> "Andreas Ntaflos"
> <[EMAIL PROTECTED]> wrote in
> message news:[EMAIL PROTECTED]
>   
>> On Friday 05 September 2008 23:59:25 Igor Tandetnik wrote:
>> 
>>> Define "weak entity". Precisely what properties does it have that are
>>> not represented in the model?
>>>   
>> A weak entity has no possible combination of attributes that would
>> uniquely identify it in the relational model. It's existence depends
>> on another entity. The building-room-example illustrates this nicely.
>> There's nothing to hinder two separate, uniquely identifiable
>> buildings to have the same room number scheme, so to identify a
>> single room the key of the building is needed in combination with the
>> room's numer.
>> 
>
> Well, in this case you've violated your "conceptual model" the moment 
> you decided to assign unique auto-generated numbers to your rooms, in a 
> way completely divorced from how numbers would be assigned to real rooms 
> in real buildings. As the room is no longer a "weak entity" by your 
> definition, of course you have difficulty modeling it as one. Why again 
> are you surprised?
>
>   
>> The property the desired model has that are not represented in this
>> model we discuss is that a room's primary key does not contain a
>> reference to the primary key of the owning entity. It is globally and
>> uniquely identifiable without ever looking at the building.
>> 
>
> And that is bad because...?
>
>   
>> This is a practical consequence and thus the model you propose is
>> possible and probably even feasible, but it is no longer the model I
>> wanted to implement. Plus I don't really see why it would be wrong to
>> use an auto-incrementing key for the roomID while keeping the tuple
>> (roomID, buildingID) as a primary key.
>> 
>
> What's the point? What's so special about PRIMARY KEY that you 
> absolutely must have one? All it does is guarantee uniqueness - but you 
> already have that. You are getting hung up on the syntax of your CREATE 
> TABLE statement, rather than on the properties of the underlying 
> relation.
>
> Let's put it this way: are there any queries that you can't run against 
> the current model, but would be able to run against your hypothetical 
> ideal model? And if there are no such queries, what's the difference 
> between the two?
>
>   
>> It s

Re: [sqlite] Any equivalent to MSSQL's UPDATE..FROM.. clause ?

2008-08-22 Thread Francis GAYREL
I met the same issue. REPLACE is the right way to override it.
Assuming C1 is the primary key or at least unique,
instead of
UPDATE T1 INNER JOIN T2 ON T1.C1=T2.C1 
SET T1.C2=T2.C2
WHERE T1.C2<>T2.C2;

you can write:
REPLACE INTO T1
SELECT T1.C1,T2.C2,C3,C4 FROM T1 INNER JOIN T2 ON T1.C1=T2.C1
WHERE T1.C2<>T2.C2;
Beware, SELECT shall include the full T1 column set


Samuel Neff a écrit :
> I'm trying to update records in one table based on joined data in another
> table.  MSSQL has support for a "FROM" clause within an UPDATE statement
> which makes this type of thing very easy.  Is there any equivalent in
> SQLite?  The only way I've found to achive the same results is to use a
> subselect within the SET clause of the UPDATE statement, but that requires
> duplicating the WHERE clause within the subselect which is a lot of extra
> typing and I'm sure a lot of extra work for SQLite.
>
> MSSQL:
>
> UPDATE T1
> SET
> A = T2...,
> B = T2...,
> C = T2...,
> FROM T1 INNER JOIN T2 ON 
>
> SQLite:
>
> UPDATE T1
> SET
> A = (SELECT ... FROM T1 T1_Inner INNER JOIN T2 ON ... WHERE T1_Inner.RowID =
> T1.RowID),
> B = (SELECT ... FROM T1 T1_Inner INNER JOIN T2 ON ... WHERE T1_Inner.RowID =
> T1.RowID),
> C = (SELECT ... FROM T1 T1_Inner INNER JOIN T2 ON ... WHERE T1_Inner.RowID =
> T1.RowID),
> ...
>
> Here are samples of equivalent code in MSSQL and SQLite.  Is there a way to
> simplify the UPDATE statement in the SQLite code?
>
> I'm not replacing the target row entirely, I don't think INSERT OR REPLACE
> will work in this scenario.
>
> Thanks,
>
> Sam
>
> --
> -- MSSQL
> --
>
> CREATE TABLE #T1(
> ID INTEGER PRIMARY KEY IDENTITY,
> A VARCHAR(100),
> B VARCHAR(100),
> C VARCHAR(100));
>
> CREATE TABLE #T2(
> ID INTEGER PRIMARY KEY IDENTITY,
> A VARCHAR(100),
> B VARCHAR(100),
> C VARCHAR(100));
>
> INSERT INTO #T1 VALUES ('a1', 'b1', 'c1');
> INSERT INTO #T1 VALUES (NULL, 'b2', 'c2');
> INSERT INTO #T1 VALUES ('a3', NULL, 'c3');
> INSERT INTO #T1 VALUES ('a4', 'b4', NULL);
>
> INSERT INTO #T2 VALUES ('A1', 'B1', 'C1');
> INSERT INTO #T2 VALUES ('A2', NULL, 'C2');
> INSERT INTO #T2 VALUES ('A3', 'B3', NULL);
> INSERT INTO #T2 VALUES (NULL, 'B4', 'C4');
>
> SELECT * FROM #T1;
> SELECT * FROM #T2;
>
> UPDATE#T1
> SETA = COALESCE(#T1.A, #T2.A),
> B = COALESCE(#T1.B, #T2.B),
> C = COALESCE(#T1.C, #T2.C)
> FROM#T1 INNER JOIN #T2 ON #T1.ID = #T2.ID;
>
> SELECT * FROM #T1;
>
> DROP TABLE #T1;
> DROP TABLE #T2;
>
> --
> -- SQLite
> --
>
> CREATE TEMP TABLE T1(
> ID INTEGER PRIMARY KEY AUTOINCREMENT,
> A TEXT,
> B TEXT,
> C TEXT);
>
> CREATE TEMP TABLE T2(
> ID INTEGER PRIMARY KEY AUTOINCREMENT,
> A TEXT,
> B TEXT,
> C TEXT);
>
> INSERT INTO T1 VALUES (NULL, 'a1', 'b1', 'c1');
> INSERT INTO T1 VALUES (NULL, NULL, 'b2', 'c2');
> INSERT INTO T1 VALUES (NULL, 'a3', NULL, 'c3');
> INSERT INTO T1 VALUES (NULL, 'a4', 'b4', NULL);
>
> INSERT INTO T2 VALUES (NULL, 'A1', 'B1', 'C1');
> INSERT INTO T2 VALUES (NULL, 'A2', NULL, 'C2');
> INSERT INTO T2 VALUES (NULL, 'A3', 'B3', NULL);
> INSERT INTO T2 VALUES (NULL, NULL, 'B4', 'C4');
>
> SELECT * FROM T1;
> SELECT * FROM T2;
>
>
> -- here's the ugly statement I'd like to simplfy
>
> UPDATET1
> SETA = (
> SELECT COALESCE(InnerT1.A, T2.A)
> FROM T1 InnerT1, T2
> WHERE InnerT1.ID = T1.ID
>   AND T2.ID = T1.ID
> ),
>B = (
> SELECT COALESCE(InnerT1.B, T2.B)
> FROM T1 InnerT1, T2
> WHERE InnerT1.ID = T1.ID
>   AND T2.ID = T1.ID
> ),
>C = (
> SELECT COALESCE(InnerT1.C, T2.B)
> FROM T1 InnerT1, T2
> WHERE InnerT1.ID = T1.ID
>   AND T2.ID = T1.ID
> )
> ;
>
> SELECT * FROM T1;
>
> DROP TABLE T1;
> DROP TABLE T2;
>
>
> -
> We're Hiring! Seeking passionate Flex, C#, or C++ (RTSP, H264) developer in
> the Washington D.C. Contact [EMAIL PROTECTED]
> ___
> sqlite-users mailing list
> sqlite-users@sqlite.org
> http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users
>
>
>   

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] How to use the ROWID of the last inserted row for FK insert into other tables?

2008-08-21 Thread Francis GAYREL
Why two tables? Define a unique table and  redefine your tables as views.

alp a écrit :
> Hello, 
>
> I have to tables(TBL_OBJECTS, TBL_TAGS) and I want to use the ROWID of the
> last inserted row from table TBL_OBJECTS to insert a new row in TBL_TAGS
> table with the ID_OBJECT foreign key set to the ROWID value from the
> precedent table. 
>
> This is the tables definition:
>
> CREATE TABLE TBL_OBJECTS (
>   IDinteger PRIMARY KEY NOT NULL,
>   DATA  text,
>   PATH  text
> );
>
> CREATE TABLE TBL_TAGS (
>   ID   integer PRIMARY KEY NOT NULL,
>   ID_TAG_TYPE  integer NOT NULL,
>   ID_OBJECTinteger NOT NULL,
>   TAG_DATA text NOT NULL
> );
>
>
> My solution is:
>
> INSERT INTO TBL_OBJECTS
>   (DATA,
>   PATH)
>   VALUES ('val1', 'val2');
>
>   INSERT INTO TBL_TAGS
>   (ID_TAG_TYPE,
>   ID_OBJECT,
>   TAG_DATA)
>   VALUES (1, 2, 'a'); --doesn't count what value is inserted for ID_OBJECT
> as it will be changed in the next statement  
>
> UPDATE TBL_TAGS SET ID_OBJECT = (SELECT MAX(ROWID) FROM TBL_OBJECTS)
> WHERE ROWID = (SELECT MAX(ROWID) FROM TBL_TAGS);
>
> but I am sure there is a less complex one that you can point out to me.
>   

___
sqlite-users mailing list
sqlite-users@sqlite.org
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users