2011-05-19 46 views
2

我想執行的三種型號/表這個查詢:如何聯接三個多到許多機型,具有雙連接條件

-- get all items that don't have a status for this member 
SELECT i.* 
FROM 
mock_item i 
LEFT JOIN mock_itemstatusmember ism ON i.id = ism.item_id AND ism.member_id = 2 

WHERE 
ism.id IS NULL 

這裏是怎麼我的模型看:

from django.db import models 

# think status as a status 
class Member(models.Model): 
    id = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=255) 

class Status(models.Model): 
    id = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=255) 
    no = models.SmallIntegerField() 

class Item(models.Model): 
    id = models.AutoField(primary_key=True) 
    name = models.CharField(max_length=255) 
    status = models.ManyToManyField(Status, through='ItemStatusMember') 
    member = models.ManyToManyField(Member, through='ItemStatusMember')  


class ItemStatusMember(models.Model): 
    """ 
    Table that keeps job statuss information for a user. 
    Tides Items with Members with Statuss 
    """ 
    id = models.AutoField(primary_key=True) 
    member = models.ForeignKey(Member) 
    status = models.ForeignKey(Status) 
    item = models.ForeignKey(Item) 

,但其數據庫的樣本數據:

mysql> select * from mock_member; 
+----+--------+ 
| id | name | 
+----+--------+ 
| 1 | Stefan | 
| 2 | Alex | 
| 3 | Diana | 
+----+--------+ 
3 rows in set (0.00 sec) 

mysql> select * from mock_status; 
+----+---------+----+ 
| id | name | no | 
+----+---------+----+ 
| 1 | Pending | 1 | 
| 2 | Success | 2 | 
+----+---------+----+ 
2 rows in set (0.00 sec) 

mysql> select * from mock_item; 
+----+----------------+ 
| id | name   | 
+----+----------------+ 
| 1 | My first item | 
| 2 | My second item | 
| 3 | My third item | 
+----+----------------+ 
3 rows in set (0.00 sec) 

mysql> select * from mock_itemstatusmember; 
+----+-----------+-----------+---------+ 
| id | status_id | member_id | item_id | 
+----+-----------+-----------+---------+ 
| 1 |   1 |   1 |  1 | 
| 2 |   2 |   1 |  2 | 
| 3 |   1 |   2 |  1 | 
+----+-----------+-----------+---------+ 
3 rows in set (0.00 sec) 

我需要這個,用ORM,而不是與來自ORM的原始SQL查詢工具來獲取所有我沒有這個成員的狀態的tems。

在這個問題開頭的SQL查詢做到這一點,所以有

AND ism.member_id = 2 

條件作爲第二條件,左連接的一部分是很重要的,而不是移動到where,我知道怎麼做。

回答

1
from django.db.models import Q  
Item.objects.filter(~Q(member__id=2)) 
+0

嗨,您的過濾器生成的查詢,移動where子句中的member_id = 2條件。所以它沒有結果。我在問題中編寫的查詢給出了兩個結果(item_id = 2和item_id 3)。 – StefanH 2011-05-20 08:03:00

+0

在意識到我沒有得到我的觀點後,我試圖達到500分,我決定回顧一下我的答案。在仔細看看你的SQL之後,我注意到你試圖用我自己的話來做的事是獲得不屬於成員2的項目。我已經更新了我的代碼來做到這一點。但是,實際的ORM生成的SQL將與您的不同。如果你只是想要結果,它應該沒問題,但如果你想要底層的SQL是相同的,那麼它對你來說是沒有用的。 – solartic 2011-05-21 21:06:53

+0

是的,就像一個魅力:)它有點神奇,它知道如何用這麼簡短的語法來完成我所需要的。我查看了查詢語句,查詢語句如下:SELECT'mock_item'.'id','mock_item'.'name' FROM'mock_item' WHERE NOT((''mock_item'.'id' IN(SELECT U1 .'item_id' FROM'mock_itemstatusmember' U1 WHERE(U1.'member_id' = 2 AND U1.'item_id' NOT NOT NULL))和'mock_item'.'id'不是NULL)) - 我也可以適應抓取項目處於用戶狀態,這是下一步:q = Item.objects.filter(Q(member_id = 2)&Q(status_id = 1))。謝謝 ! – StefanH 2011-05-22 12:12:01