- From: Eric Prud'hommeaux <eric@w3.org>
- Date: Tue, 16 Nov 2004 01:42:53 -0500
- To: Simon Raboczi <raboczi@tucanatech.com>
- Cc: public-rdf-dawg@w3.org
- Message-ID: <20041116064252.GA13411@w3.org>
On Mon, Nov 15, 2004 at 12:11:49PM -0500, Eric Prud'hommeaux wrote: > On Tue, Nov 16, 2004 at 12:42:39AM +1000, Simon Raboczi wrote: > > > > > > On 15/11/2004, at 20:50, Eric Prud'hommeaux wrote: > > > > > > > >Related to > > > ACTION SimonR: explain how much of disjuction can be done with > > > optionals, nested or otherwise. Point to references, problems with > > > LEFT OUTER JOIN in the literature. > > > > > >In my experiments, I haven't found DISJUNCTION that I couldn't > > >implement with OUTER JOINs. > > > > I haven't quite gotten the trick yet, embarrassingly enough. > > It's been my default problem for the last 15 months. I've got a LOT > of time into it (probably could have been shortcutted with some > measure of education, though). > > > Can you > > demonstrate for the simplest case of > > > > SELECT ?a ?b WHERE (?a <x:p1> <x:o1>) UNION (?b <x:p2> <x:o2>) > > > > targeting a graph with the following triples > > > > <x:s1> <x:p1> <x:o1> . > > <x:s2> <x:p2> <x:o2> . On IRC, Andy proposed: 2004-11-15T15:08:28Z <AndyS> SELECT a, NULL as b WHERE stmt.p = x:p1 stmt.o = o1 UNION 2004-11-15T15:08:28Z <AndyS> SELECT a as NULL, b WHERE stmt.p = x:p2 stmt.o = o2 2004-11-15T15:08:47Z <AndyS> (with apologies to SQL!) I tried it out in MySQL 4.0.22 and found a mysql bug: SELECT h1.s AS a, NULL as b FROM holds AS h1 WHERE h1.p = "x:p1" AND h1.o = "x:o1" UNION SELECT NULL as a, h1.s AS b FROM holds AS h1 WHERE h1.p = "x:p2" AND h1.o = "x:o2"; +------+------+ | a | b | +------+------+ | x:s1 | NULL | | NULL | | +------+------+ But it *does* work in last night's nightly build of mysql 4.1 *. +------+------+ | a | b | +------+------+ | x:s1 | NULL | | NULL | x:s2 | +------+------+ Gosh, that's much simpler than the hoops I was jumping through re-using table aliases and creating complex scalar constraints. * Install instructions ('cause they are rather opaque): cd /usr/local/src/ wget http://downloads.mysql.com/snapshots/mysql-4.1/mysql-4.1.8-nightly-20041115.tar.gz tar xzf mysql-4.1.8-nightly-20041115.tar.gz cd mysql-4.1.8-nightly-20041115 ./configure make make install LD_LIBRARY_PATH=/usr/local/lib/mysql /usr/local/bin/mysql_install_db LD_LIBRARY_PATH=/usr/local/lib/mysql /usr/local/bin/mysqld_safe & LD_LIBRARY_PATH=/usr/local/lib/mysql /usr/local/bin/mysql I needed write privs to /usr/local/ -R and create for /tmp/mysql.sock to do this > > I'd expect the result > > > > +--------+--------+ > > | ?a | ?b | > > +--------+--------+ > > | <x:s1> | | > > | | <x:s2> | > > +--------+--------+ > > The OUTER JOIN trick is only required when the paths through the > disjunction involve different table aliases. In this case, we can > express both sides of the disjunction with the same table alias (h1 > in the example): > > INSERT INTO holds (s, p, o) VALUES ('x:s1', 'x:p1', 'x:o1'); > INSERT INTO holds (s, p, o) VALUES ('x:s2', 'x:p2', 'x:o2'); > > SELECT h1.s AS _L1_a_R1_b, > (h1.p="x:p1" AND h1.o="x:o1") AS _L1, > (h1.p="x:p2" AND h1.o="x:o2") AS _R1 > FROM holds as h1 > WHERE ((h1.p="x:p1" AND h1.o="x:o1") > OR (h1.p="x:p2" AND h1.o="x:o2")) > > +------------+------+------+ > | _L1_a_R1_b | _L1 | _R1 | > +------------+------+------+ > | x:s1 | 1 | 0 | > | x:s2 | 0 | 1 | > +------------+------+------+ > > It also depends on how you store your data. If it's in > predicate-specific tables like: > > CREATE TABLE p1s (id INTEGER NOT NULL AUTO_INCREMENT, > s VARCHAR(80), > p1 VARCHAR(80), > PRIMARY KEY(id)); > INSERT INTO p1s (s, p1) VALUES ("x:s1", "x:o1"); > CREATE TABLE p2s (id INTEGER NOT NULL AUTO_INCREMENT, > s VARCHAR(80), > p2 VARCHAR(80), > PRIMARY KEY(id)); > INSERT INTO p2s (s, p2) VALUES ("x:s2", "x:o2"); > > the alias are distinct so the OUTER JOIN hatchet needs to come out: > > CREATE TABLE true (truth VARCHAR(20)); > INSERT INTO true (truth) VALUES ("sure, why not"); > > SELECT p1s1.s AS a, p2s1.s AS b > FROM true > LEFT OUTER JOIN p1s AS p1s1 ON 1 > LEFT OUTER JOIN p2s AS p2s1 ON 1 > WHERE (p1s1.p1="x:o1" > OR p2s1.p2="x:o2") > > this is asking more of a simultaneous solutions question and begets: > +------+------+ > | a | b | > +------+------+ > | x:s1 | x:s2 | > +------+------+ > > Here we get to the cutting edge of my sleep research. I'm going to > sleep now -- perhaps something will percolate by morning. > > > What's the equivalent SPARQL using [ ] instead of UNION? > > The simple way would be to again reduce the sides of the conjunction > to a single triple as we did in SQL: > > SELECT ?a ?b WHERE (?s ?p ?o) > AND ((?p=<x:p1> AND ?o=<x:o1>) > OR (?p=<x:p2> AND ?o=<x:o2>)) > > If you want a challenge, and add NULLs to the language, maybe you can > do it was a disjunction. You need a throw-away truth for this. > Something like > > moon madeOf greenCheese . > > SELECT ?a ?b WHERE (moon madeOf greenCheese) > [?a <x:p1> <x:o1>] > [?b <x:p2> <x:o2>] > AND (?a IS NULL OR ?b IS NULL) > > but that assumes that you'll get a match on the astronomical trivia. > You can be more assured that (?s ?p ?o) will match, and since the > results are a set, you get no more logical results, but that might > be a bit pricey to actually execute. > -- > -eric > > office: +81.466.49.1170 W3C, Keio Research Institute at SFC, > Shonan Fujisawa Campus, Keio University, > 5322 Endo, Fujisawa, Kanagawa 252-8520 > JAPAN > +1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA > cell: +1.857.222.5741 (does not work in Asia) > > (eric@w3.org) > Feel free to forward this message to any list for any purpose other than > email address distribution. -- -eric office: +81.466.49.1170 W3C, Keio Research Institute at SFC, Shonan Fujisawa Campus, Keio University, 5322 Endo, Fujisawa, Kanagawa 252-8520 JAPAN +1.617.258.5741 NE43-344, MIT, Cambridge, MA 02144 USA cell: +1.857.222.5741 (does not work in Asia) (eric@w3.org) Feel free to forward this message to any list for any purpose other than email address distribution.
Received on Tuesday, 16 November 2004 06:42:53 UTC