2010-09-22 53 views
1

在寫這篇文章之前,我仍然在學習SQL,所以我現在有點尷尬。幫我解決如何爲這個JOIN場景構建我的SQL

我的情況是這樣的:

  1. 我有幾個名爲「任務」有自動遞增的主鍵ID和一個文本字段的表(以及其他不相關的這個問題,太)。
  2. 我有另一個表稱爲'位置'與一個外鍵引用一個任務的ID和一個文本字段代表位置的名稱。這些地圖集的位置給予特定的任務(我認爲這是所謂的一對多)。
  3. 我在我的代碼中包含一個位置值列表的數據結構。我想要查詢至少具有與它們相關的所有這些位置的任務。
  4. 我將有其他具有類似一對多關係的表格,以及我需要用作任務查詢的基礎。它們也可能用於過濾彼此的查詢結果。如何在我的SQL使用中堆疊這些類型的過濾器中的幾種(而不是在我的代碼中手動結果集之間的AND操作)?

它似乎應該很簡單,但我想我現在根本就缺乏想象力。這些問題對我來說會有更多的問題,所以看到解決這個問題的例子也會對這些問題有所幫助。

回答

0

我剛剛測試過一個小東西:

SELECT * 
FROM Tasks 
WHERE ID IN 
    (
    SELECT l.ID 
    FROM Location l 
    WHERE l.Loc_name IN ('loc1','loc2','loc3') 
    GROUP BY l.ID 
    HAVING COUNT(l.Loc_name) = 3 -- Number of all location u have in the in clause 
); 

什麼ü需要做的是設置了有聖誕老人的數量。

只有當任務沒有相同的位置兩次或更多時,這纔會起作用。

你甚至可以爲每個位置做一個Exists子句,但前提是它的靜態

+0

這可能工作... – Hamster 2010-09-22 22:13:55

+0

即時通訊仍然想着更好的方式,但atm我沒有得到一個; - / – domiSchenk 2010-09-23 06:07:29

0

試試這個:

Select TaskId, LocationName from Task, Location where 
Task.TaskId = Location.TaskId and 
LocationName in (<all the locations you want to query against>) 

您可以發送一個逗號分隔的位置列表,並在此查詢使用。如果您想使查詢可伸縮,則可以創建返回有效/過濾列表的小SP,並將其他SP用作輸入。你也可以處理這是在編碼方面(而不是sql)。

+0

不需要JOIN?有趣。但是,這是否也確保任務至少具有我所有的位置? – Hamster 2010-09-22 13:01:22

+0

nope它會給你至少一個位置在列表中的所有任務 – domiSchenk 2010-09-22 13:03:53

+0

單獨的問題:是否需要使用「GROUP BY TaskID」來確保返回單個任務?我知道這並不能解決'至少一個位置'的問題,儘管... – Hamster 2010-09-22 13:06:31

0

我從你的描述中得到什麼

declare @tasks table 
(
    taskid int, 
    taskname varchar(20) 
) 

declare @locations table 
(
    locationid int, 
    taskid int, 
    locationname varchar(20) 
) 

insert into @tasks select 1, 'task1' 
insert into @tasks select 2, 'task2' 
insert into @tasks select 3, 'task3' 

insert into @locations select 1, 1, 'location1' 
insert into @locations select 2, 1, 'location2' 
insert into @locations select 3, 1, 'location3' 
insert into @locations select 4, 2, 'location4' 
insert into @locations select 5, 2, 'location5' 
insert into @locations select 6, 3, 'location6' 

select t.taskid, t.taskname, l.locationid, l.locationname 
from @tasks t inner join @locations l on t.taskid = l.taskid 
where l.locationname in ('location1', 'location4') -- OR locationid 

-- You can alos do this like 
select t.taskid, t.taskname, l.locationid, l.locationname 
from @tasks t inner join @locations l on t.taskid = l.taskid 
where l.locationname in (select top 2 locationname from @locations order by locationid desc)