加入三个表并尝试获取空值

时间:2011-02-10 03:04:44

标签: sql sql-server tsql

我有三个表:tblProduct,lkpFoodgroup,tblCustomer。和一个联结表:jctCustomerFoodgroup

列是这样的:

**tblProduct**
+---+----------------+
|PK |int_ProductID   |
|FK |int_FoodgroupID |
|   |str_ProductName |
+---+----------------+

**lkpFoodgroup**
+---+-------------------+
|PK |int_FoodgroupID    |
|   |str_FoodgroupHandle|
+---+-------------------+

**tblCustomer**
+---+----------------+
|PK |int_CustomerID  |
|   |str_CustomerName|
+---+----------------+

**jctCustomerFoodgroup**
+---+----------------+
|PK |int_CustomerID  |
|PK |int_FoodgroupID |
|   |int_ProductID   |
+---+----------------+

这些表中最简单的是查找:

**lkpFoodgroup**
+---------------+-------------------+
|int_FoodgroupID|str_FoodgroupHandle|
+---------------+-------------------+
|1              |fruit              |
|2              |meat               |
|3              |bread              |
|4              |cheese             |
+---------------+-------------------+

接下来是客户:

**tblCustomer**
+----------------+-------------------+
|int_CustomerID  |str_CustomerName   |
+----------------+-------------------+
|1               |Bob                |
|2               |Sally              |
|3               |Jane               |
|4               |Billy              |
+----------------+-------------------+

tblProduct上可能有许多产品具有相同的Foodgroup。还有一些产品Foodgroups没有产品:

**tblProduct**
+---------------+-----------------+----------------+
|int_ProductID  |int_FoodgroupID  |str_ProductName |
+---------------+-----------------+----------------+
|1              |1                |apple           |
|2              |1                |banana          |
|3              |1                |orange          |
|4              |1                |pear            |
|5              |2                |chicken         |
|6              |2                |beef            |
|7              |2                |fish            |
|8              |2                |turkey          |
|9              |3                |white           |
|10             |3                |wheat           |
+---------------+-----------------+----------------+

联结表上的PK是一个组合的int_CustomerID和int_FoodgroupID - 这意味着任何客户只能为每个Foodgroup选择一个产品:

**jctCustomerFoodgroup**
+---------------+-----------------+--------------+------------------------+
|int_CustomerID |int_FoodgroupID  |int_ProductID |  --meaning             |
+---------------+-----------------+--------------+------------------------|
|1              | 1               |1             | --Bob, fruit, apple    |
|1              | 2               |6             | --Bob, meat, beef      |
|1              | 3               |9             | --Bob, bread, white    |
|2              | 1               |3             | --Sally, fruit, orange |
|2              | 2               |5             | --Sally, meat, chicken |
|3              | 1               |3             | --Jane, fruit, orange  |
|3              | 3               |9             | --Jane, bread, white   |
|3              | 2               |6             | --Jane, meat, beef     |
+---------------+-----------------+--------------+------------------------+

我正在寻找一个可以给我这样结​​果的查询:

**spGetCustomerProductSelections(1) --Get Bob's choices**
+----------------+---------------+-------------------+-------------+---------------+
|int_CustomerID  |int_FoodgroupID|str_FoodgroupHandle|int_ProductID|str_ProductName|
+----------------+---------------+-------------------+-------------+---------------+
|1               |1              |fruit              |1            |apple          |
|1               |2              |meat               |6            |beef           |
|1               |3              |bread              |9            |white          |
|1               |4              |cheese             |null         |null           |
+----------------+---------------+-------------------+-------------+---------------+

**spGetCustomerProductSelections(2) --Get Sally's choices**
+----------------+---------------+-------------------+-------------+---------------+
|int_CustomerID  |int_FoodgroupID|str_FoodgroupHandle|int_ProductID|str_ProductName|
+----------------+---------------+-------------------+-------------+---------------+
|2               |1              |fruit              |3            |orange         |
|2               |2              |meat               |5            |chicken        |
|2               |3              |bread              |null         |null           |
|2               |4              |cheese             |null         |null           |
+----------------+---------------+-------------------+-------------+---------------+

**spGetCustomerProductSelections(4) --Get Billy's choices**
+----------------+---------------+-------------------+-------------+---------------+
|int_CustomerID  |int_FoodgroupID|str_FoodgroupHandle|int_ProductID|str_ProductName|
+----------------+---------------+-------------------+-------------+---------------+
|4               |1              |fruit              |null         |null           |
|4               |2              |meat               |null         |null           |
|4               |3              |bread              |null         |null           |
|4               |4              |cheese             |null         |null           |
+----------------+---------------+-------------------+-------------+---------------+

任何帮助?

2 个答案:

答案 0 :(得分:0)

您应该使用外连接(左,右或全)。这些连接将包含空值。

答案 1 :(得分:0)

请不要将您的程序命名为以“sp”开头。它将开始在master数据库中搜索,之后才会回到你的数据库。

您的架构和数据的DDL

create table lkpFoodgroup
(int_FoodgroupID int, str_FoodgroupHandle varchar(max))
insert lkpFoodgroup values
(1,'fruit'),
(2,'meat'),
(3,'bread'),
(4,'cheese');

create table tblCustomer
(int_CustomerID int, str_CustomerName varchar(max))
insert tblCustomer values
(1,'Bob'),
(2,'Sally'),
(3,'Jane'),
(4,'Billy');

create table tblProduct
(int_ProductID int, int_FoodgroupID int, str_ProductName varchar(max))
insert tblProduct values
(1,'1','apple'),
(2,'1','banana'),
(3,'1','orange'),
(4,'1','pear'),
(5,'2','chicken'),
(6,'2','beef'),
(7,'2','fish'),
(8,'2','turkey'),
(9,'3','white'),
(10,'3','wheat');

create table jctCustomerFoodgroup
(int_CustomerID int, int_FoodgroupID int, int_ProductID varchar(max))
insert jctCustomerFoodgroup values
(1,'1','1'),
(1,'2','6'),
(1,'3','9'),
(2,'1','3'),
(2,'2','5'),
(3,'1','3'),
(3,'3','9'),
(3,'2','6');

存储过程代码

create proc uspGetCustomerProductSelections @customerID int as
select c.int_CustomerID, l.int_FoodgroupID, l.str_FoodgroupHandle, j.int_ProductID, p.str_ProductName
from tblCustomer c
cross join lkpFoodgroup l
left join jctCustomerFoodgroup j on j.int_CustomerID = c.int_CustomerID and j.int_FoodgroupID = l.int_FoodgroupID
left join tblProduct p on p.int_ProductID = j.int_ProductID
where c.int_CustomerID = @customerID

示例执行

exec uspGetCustomerProductSelections 1

输出

int_CustomerID int_FoodgroupID str_FoodgroupHandle  int_ProductID  str_ProductName
-------------- --------------- ---------------------------------------------------
1              1               fruit                1              apple
1              2               meat                 6              beef
1              3               bread                9              white
1              4               cheese               NULL           NULL