开发者

Complex - returning information that is not found in the database

I have a strange query to perform from a website. I have sets of arrays that contain pertinent ids from a many tables - 1 table per array. For example (the array name is the name of the table):

Array Set 1:
array "q": 1,2,3
array "u": 1,5
array "k": 7

Array Set 2:
array "t":   2,12
array "o":  8, 25

Array Set 3 (not really a set):
array "e": 5

I have another table, Alignment, which is not represented by the arrays. It performs a one to many relationship, allowing records from tables q,u, and k (array set 1, and recorded as relType/relID in the table) to be linked to records from t and o (array set 2, recorded as keyType/keyID) and e (array set 3, recorded as keyType/keyID). Example below:

Table: Alignment
 id   keyType  keyID   relType  relID 
 1       e       5        q       1
 2       o       8        q       1
 3       o       8        u       1
 4       t       2        q       2
 5       t       2        k       7
 6       t      12        q       1

So, in record 6, a record with an id of 12 from table t is being linked to a record with an id of 1 from table q.

I have to find missing links. The ideal state is that each of the ids from array set 1 have a record in the alignment table linking them to at least 1 record from array set 2. In the example, alignment record 1 does not count towards this goal, because it aligns a set 1 id to a set 3 id (instead of set 2).

Scanning the table, you can quickly see that there are some missing ids from array set 1: "q"-3 and "u"-5.

I've been doing this with script, by looping through each set 1 array and looking for a corresponding record, which generates a whole bunch of sql calls and really kills any page that calls this function.

Is there some way I could accomplish this in a single sql statement?

What would I like the results to look like (ideally):

recordset (consisting magically of data that didn't exist in the table):

relType   |    relID
    q            3
    u            5

However, I would be elated with even a binary type answer from the database - were all the proper ids found: true or false? (Though the missing records array is required for other functions, but at least I'd be able to choose between the fast and slow options).

Oh, MySQL 5.1.

User Damp gave me an excellent answer using a temporary table, a join, and an IS NULL statement. But it was before I added in the wrinkle that there was a third array set that needed to be excluded from the results, which also ruins the IS NULL part. I edited his sql statement to look like this:

SELECT *
FROM k2
LEFT JOIN alignment
USING ( relType, relID )
HAVING alignment.keyType IS NULL
OR alignment.keyType = "e"

I've also tried it with a Group By relID (i always thought that was a requirement of the HAVING clause). The problem is that my result set includes "q"-1, which is linked to all three types of records ("o","t", and "e"). I need this result excluded, but I'm not sure how.


Here's the sql I ended up with:

SELECT *
FROM k2
LEFT JOIN (

    SELECT *
    FROM alignment
    WHERE keyType != 'e' and 
    ( 
    (relType = 'q' AND relID IN ( 1, 2, 3 ))
    OR 
    (relType = 'u' AND relID IN ( 1, 5 ))
    OR 
    (relType = 'k' AND relID IN ( 7 ))
    )

    )A
    USING ( relType, relID )
    HAVING keyType Is Null

I have to dump the values for the IN qualifiers开发者_C百科 with script. The key was not to join to the alignment table directly.


You can try to go this route:

DROP TABLE IF EXISTS k2;
CREATE TEMPORARY TABLE k2 (relType varchar(10),relId int);
INSERT INTO k2 VALUES 
  ('q',1),
  ('q',2),
  ('q',3),
  ('u',1),
  ('u',5),
  ('k',7);
SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
HAVING Alignment.keyType IS NULL 

This should work well for small tables. Not sure about very large ones though...

EDIT

If you wanted to add a WHERE statement the query would be as follow

SELECT * FROM k2
LEFT JOIN Alignment USING(relType,relId)
WHERE Alignment.keyType != 'e'
HAVING Alignment.keyType IS NULL 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜