Jeg vil foreslå en UNION query, hvor du først søger efter de topic_ids læst af bruger 53, og derefter søger efter de topics der ikke i topic_tracs har en bruger_id 53. Såsom (ikke testet):
SELECT T.topic_id, TT.mark_time, 'laest'
FROM topics T
JOIN topics_track TT ON TT.topic_id = T.topic_id
WHERE TT.user_id = 53
UNION
SELECT topic_id, '', 'ulaest'
FROM topics
WHERE topic_id NOT IN(SELECT topic_id FROM topic_track WHERE user_id = 53)
ORDER BY topic_id
Tak for buddet, Christian. Har selv overvejet UNION. Det skal dog nævnes, at listen bliver genereret globalt under forummet, så sql'en skulle gerne være nogenlunde hurtig, hvis databasen skal kunne holde til den. Brug af både UNION og IN er temmelig hårde kald for databasen (specielt sidstnævne). Jeg var mere på udkig efter en god JOIN løsning, hvor man kunne få alle topics med i table topics også selvom der ikke var en tilsvarende værdi i table topics_track - og i disse tilfælde få en NULL-værdi el.lign. ud som mark_time. Er slet ikke klar over, om problemet kan løses. I så fald skal jeg gerne give point for dit svar :-)
Om det kan løses uden UNION ved jeg ikke (jeg ventede med dette svar for at se, om andre i mellemtiden havde en løsning). Jeg eksperimenterede med IF, men fandt ikke noget der virkede. Jeg opretter svar, som du bad om.
proev:
SELECT t.topic_id, tt.mark_time
FROM topics as t LEFT JOIN topics_track as tt ON tt.topic_id=t.topic_id
WHERE (tt.user_id=53 OR tt.user_id IS NULL) order by T.topic_id;
Tak for buddet, Arne. Sql'en virker dog ikke, men crasher databasen. Table topics_track er selvfølgelig meget stor, og ved at benytte "user_id IS NULL"
medtages alle resultater på samtlige user_id, der endnu ikke forekommer i topics_track - samt resultater på user_id 53. Det er en meget stor mængde data!
Er du vitterlig ikke nogen, der kan løse denne sql udfordring? Det er jo en relativ generel problematik indenfor anvendelse af sql JOINs:
Der skal uddrages alle poster fra tabel A med en tilhørende værdi V fra tabel B, hvor de to tabeller har en id relation. Hos de poster fra A uden sammenfald med B skal returneres NULL i stedet for V.
Det må da være en typisk problemstilling rigtig mange før mig er stødt på?
Ingen bud?
Det er et kendt problem med en kendt loesning:
mysql> CREATE TABLE topics_track (
-> user_id INTEGER NOT NULL,
-> topic_id INTEGER NOT NULL,
-> mark_time VARCHAR(50),
-> PRIMARY KEY (user_id,topic_id)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql>
mysql> INSERT INTO topics VALUES(1);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO topics VALUES(2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO topics VALUES(3);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> INSERT INTO topics_track VALUES(52, 1, 'Mandag');
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO topics_track VALUES(52, 2, 'Tirsdag');
Query OK, 1 row affected (0.01 sec)
mysql> INSERT INTO topics_track VALUES(53, 1, 'Onsdag');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO topics_track VALUES(53, 2, 'Torsdag');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> SELECT * FROM topics;
+----------+
| topic_id |
+----------+
| 1 |
| 2 |
| 3 |
+----------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM topics_track;
+---------+----------+-----------+
| user_id | topic_id | mark_time |
+---------+----------+-----------+
| 52 | 1 | Mandag |
| 52 | 2 | Tirsdag |
| 53 | 1 | Onsdag |
| 53 | 2 | Torsdag |
+---------+----------+-----------+
4 rows in set (0.00 sec)
mysql>
mysql> SELECT t.topic_id, tt.mark_time
-> FROM topics t JOIN topics_track tt ON t.topic_id=tt.topic_id
-> ORDER BY t.topic_id;
+----------+-----------+
| topic_id | mark_time |
+----------+-----------+
| 1 | Mandag |
| 1 | Onsdag |
| 2 | Torsdag |
| 2 | Tirsdag |
+----------+-----------+
4 rows in set (0.00 sec)
mysql>
mysql> SELECT t.topic_id, tt.mark_time
-> FROM topics t JOIN topics_track tt ON t.topic_id=tt.topic_id
-> WHERE tt.user_id=53
-> ORDER BY t.topic_id;
+----------+-----------+
| topic_id | mark_time |
+----------+-----------+
| 1 | Onsdag |
| 2 | Torsdag |
+----------+-----------+
2 rows in set (0.01 sec)
mysql>
mysql> SELECT t.topic_id, tt.mark_time
-> FROM topics t LEFT JOIN topics_track tt ON t.topic_id=tt.topic_id
-> ORDER BY t.topic_id;
+----------+-----------+
| topic_id | mark_time |
+----------+-----------+
| 1 | Mandag |
| 1 | Onsdag |
| 2 | Torsdag |
| 2 | Tirsdag |
| 3 | NULL |
+----------+-----------+
5 rows in set (0.00 sec)
mysql>
mysql> SELECT t.topic_id, tt.mark_time
-> FROM topics t LEFT JOIN topics_track tt ON t.topic_id=tt.topic_id
-> WHERE tt.user_id=53 ORDER BY t.topic_id;
+----------+-----------+
| topic_id | mark_time |
+----------+-----------+
| 1 | Onsdag |
| 2 | Torsdag |
+----------+-----------+
2 rows in set (0.00 sec)
mysql>
mysql> SELECT t.topic_id, tt.mark_time
-> FROM topics t LEFT JOIN topics_track tt ON t.topic_id=tt.topic_id
-> WHERE (tt.user_id=53 OR tt.user_id IS NULL)
-> ORDER BY t.topic_id;
+----------+-----------+
| topic_id | mark_time |
+----------+-----------+
| 1 | Onsdag |
| 2 | Torsdag |
| 3 | NULL |
+----------+-----------+
3 rows in set (0.00 sec)
mysql>
mysql> DROP TABLE topics;
Query OK, 0 rows affected (0.00 sec)
mysql> DROP TABLE topics_track;
Query OK, 0 rows affected (0.00 sec)
Hvis du vil have flere raekker retur end din database og/eller app kan klare, saa har du et problem. Men det problem kan vi ikke loese.
Hej Arne
Jeg tror ikke, vi kommer videre. Men jeg synes, du er den, der kommer tættest på et svar, så hvis du vil åbne op for en pointgivning for sidste svar, så godkender jeg det.
mvh.
Thomas