如何为仅出现在一个列表中的项目创建查询

时间:2015-10-16 21:49:24

标签: sql sqlite

我正在研究的方案如下: -

  • 对食物中毒案进行了多次采访
  • 生成一个名为qryFoodInCase(fldCaseIDfldFood)的查询,其中包含所有访谈中提到的所有食物
  • 其他查询调用qryFoodInInterview(fldCaseIDfldInterviewIDfldFood)由每次访谈中提到的食物组成

现在我在sql之后进行查询,该查询将返回一个未被受访者消费但被一个或多个其他受访者消费的食物。

我最接近的是:

select Q1.fldCaseID,Q1.fldfood,Q2.fldInterviewID,fldGotSick 
from qryFoodInCases as Q1 
left join 
(select * from qryFoodInInterview where qryFoodInInterview.fldInterviewID=1) as Q2
on Q1.fldFood=Q2.fldFood 
where Q1.fldCaseID=1

字段Q2.fldInterviewID为消耗的食物返回1,为未消耗的食物返回null。但是,我不想在sql中硬编码fldInterviewID。我想在一个查询中为所有访谈返回类似的记录集。

qryFoodInCase和qryFoodInInterview的SQL如下: -

CREATE VIEW `qryFoodInCases`
AS
SELECT tblCases.fldCaseID
    ,fldfood
    ,count(tblFoodHistory.fldFoodID) AS fldFoodFrequency
FROM tblFood
INNER JOIN tblFoodHistory
    ON tblFoodHistory.fldFoodID = tblFood.fldFoodID
INNER JOIN tblMealHistory
    ON tblFoodHistory.fldMealID = tblMealHistory.fldMealHistoryID
INNER JOIN tblInterviews
    ON tblInterviews.fldInterviewID = tblMealHistory.fldInterviewID
INNER JOIN tblCases
    ON tblCases.fldCaseID = tblInterviews.fldCaseID
GROUP BY tblCases.fldCaseID, tblFood.fldFood

输出:

+-----------+------------+------------------+
| fldCaseID |  fldFood   | fldFoodFrequency |
+-----------+------------+------------------+
|         1 | Banana     |                3 |
|         1 | Beans      |                5 |
|         1 | Cabagge    |                3 |
|         1 | Chicken    |                1 |
|         1 | Pork       |                5 |
|         1 | Potatoes   |                1 |
|         1 | Rice       |                1 |
|         1 | fried fish |                1 |
|         2 | Cabagge    |                1 |
|         2 | Chicken    |                2 |
|         2 | Potatoes   |                1 |
|         2 | Rice       |                1 |
|         2 | Salad      |                1 |
+-----------+------------+------------------+

CREATE VIEW `qryFoodInInterview`
AS
SELECT tblInterviews.fldCaseID
    ,tblInterviews.fldInterviewID
    ,tblFood.fldFood
    ,tblInterviews.fldGotSick
FROM tblInterviews
INNER JOIN tblMealHistory
    ON tblInterviews.fldInterviewID = tblMealHistory.fldInterviewID
INNER JOIN tblFoodHistory
    ON tblFoodHistory.fldMealID = tblMealHistory.fldMealHistoryID
INNER JOIN tblFood
    ON tblFood.fldFoodID = tblFoodHistory.fldFoodID
GROUP BY tblInterviews.fldInterviewID, tblFoodHistory.fldFoodID

输出

+-----------+----------------+------------+------------+
| fldCaseID | fldInterviewID |  fldFood   | fldGotSick |
+-----------+----------------+------------+------------+
|         1 |              1 | Pork       |          0 |
|         1 |              1 | Banana     |          0 |
|         1 |              1 | Rice       |          0 |
|         1 |              1 | Potatoes   |          0 |
|         1 |              2 | Chicken    |          1 |
|         1 |              2 | Banana     |          1 |
|         1 |              2 | Beans      |          1 |
|         1 |              4 | Pork       |          1 |
|         1 |              4 | fried fish |          1 |
|         1 |              4 | Beans      |          1 |
|         2 |              6 | Salad      |          0 |
|         2 |              6 | Chicken    |          0 |
|         2 |              6 | Cabagge    |          0 |
|         2 |              6 | Rice       |          0 |
|         2 |              6 | Potatoes   |          0 |
|         1 |              8 | Pork       |          0 |
|         1 |              8 | Cabagge    |          0 |
|         1 |              9 | Pork       |          1 |
|         1 |              9 | Banana     |          1 |
|         1 |              9 | Beans      |          1 |
|         1 |             10 | Cabagge    |          1 |
|         1 |             10 | Beans      |          1 |
|         1 |             11 | Pork       |          1 |
|         1 |             11 | Cabagge    |          1 |
|         1 |             11 | Beans      |          1 |
+-----------+----------------+------------+------------+

2 个答案:

答案 0 :(得分:0)

SQL Fiddle Demo

  • 与所有采访者一起制作cross join所有食物
  • 然后left join看看哪一个没有采访
  • 空均值interview没有消耗food
  • 并且存在与interview消费food
  • 不同的人

SELECT F.fldFood, I.fldInterviewID, FI.fldInterviewID
FROM qryFoodInCases F, (SELECT DISTINCT fldInterviewID FROM qryFoodInInterview) I
LEFT JOIN qryFoodInInterview FI
       ON F.fldFood = FI.fldFood
      AND I.fldInterviewID = FI.fldInterviewID
WHERE FI.fldInterviewID IS NULL
AND EXISTS (SELECT 1
            FROM qryFoodInInterview Q1
            WHERE Q1.fldFood = F.fldFood
              AND Q1.fldInterviewID <> I.fldInterviewID)
;

诀窍是当时做了一件事。一旦我意识到我需要所有组合并创建交叉连接,其余的都很容易。

答案 1 :(得分:0)

select Q1.fldCaseID,Q1.fldfood,Q2.fldInterviewID,fldGotSick 
from qryFoodInCases as Q1 
left join 
(select * from qryFoodInInterview QF1
 JOIN qryFoodInInterview QF2 
 where QF1.fldInterviewID <> QF2.fldInterviewID
 AND QF1.fldInterviewID > QF2.fldInterviewID
) as Q2
on Q1.fldFood=Q2.fldFood 
where Q1.fldCaseID=1

正如您所提到的,您希望复制FoodInterviews项目,自我JOIN就足以满足您的需求。请试一试,小心我没有测试过。

修复错过的自我加入条件以修复重复项。