4

嘿,谁能帮我将下面的 5 个表加入到一个查询中?我目前有下面的查询,但似乎没有工作,好像在招聘表中有两个具有相同 ID 的产品所有产品都是从产品表返回的,这显然是错误的。

SELECT products.prod_id, products.title, products.price, product_types.name,  
listagg(suppliers.name, ',') WITHIN GROUP(ORDER BY suppliers.name) suppliers
FROM products 
INNER JOIN product_suppliers ON products.prod_id = product_suppluer.prod_id 
INNER JOIN product_types ON product_types.type_id = products.type_id 
INNER JOIN suppliers ON product_suppliers.supp_id = suppliers.supp_id 
LEFT OUTER JOIN hires ON hires.prod_id = products.prod_id 
    WHERE (hires.hire_end < to_date('21-JAN-13') OR hires.hire_start > to_date('26-JAN-13')) 
    OR hires.prod_id IS NULL 
GROUP BY products.prod_id, products.title, products.price, product_types.name

表数据:

PRODUCTS                 
--------------------------------------------
| Prod_ID  | Title   | Price   | Type_ID   |
|------------------------------------------|
| 1        | A       | 5       | 1         |
| 2        | B       | 7       | 1         |
| 3        | C       | 3       | 2         |
| 4        | D       | 3       | 3         |
|------------------------------------------|

PRODUCT_TYPES                 
----------------------
| Type_ID  | Type    |
|--------------------|
| 1        | TYPE_A  |
| 2        | TYPE_B  |
| 3        | TYPE_C  |
| 4        | TYPE_D  |
|--------------------|

PRODUCT_SUPPLIERS                 
-------------------------
| Prod_ID  | Supp_ID    |
|-----------------------|
| 1        | 1          |
| 1        | 2          |
| 2        | 2          |
| 3        | 3          |
| 4        | 4          |
|-----------------------|

SUPPLIERS                 
----------------------
| Supp_ID  | Name    |
|--------------------|
| 1        | SUPP_A  |
| 2        | SUPP_B  |
| 3        | SUPP_C  |
| 4        | SUPP_D  |
|--------------------|

HIRES                
---------------------------------------------------------------
| Hire_ID  | Prod_ID    | Cust_ID    | Hire_Start | Hire_End  |
|-----------------------|------------|------------------------|
| 1        | 1          | 1          | 22-Jan-13  | 23-Jan-13 |
| 2        | 2          | 2          | 27-Jan-13  | 29-Jan-13 |
| 3        | 1          | 3          | 30-Jan-13  | 31-Jan-13 |
|-----------------------|------------|------------|-----------|

PRODUCTS                 
--------------------------------
| Cust_ID  | Name    | Phone   |
|------------------------------|
| 1        | Cust_A  | 555-666 |
| 2        | Cust_B  | 444-234 |
| 3        | Cust_C  | 319-234 |
| 4        | Cust_D  | 398-092 |
|------------------------------|

目前查询的输出如下所示:

-------------------------------------------------------------
| Prod_ID  | Title   | Price   | Type_ID   | Suppliers      |
|------------------------------------------|----------------|
| 1        | A       | 5       | Type_A    | SUPP_A,SUPP_B |
| 2        | B       | 7       | Type_B    | SUPP_B         |
| 3        | C       | 3       | Type_C    | SUPP_C         |
| 4        | D       | 3       | Type_D    | SUPP_D         |
|------------------------------------------|----------------|

什么时候肯定应该是这个样子?因为 Prod_ID '1' 在查询中的日期之间被租用

-------------------------------------------------------------
| Prod_ID  | Title   | Price   | Type_ID   | Suppliers      |
|------------------------------------------|----------------|
| 2        | B       | 7       | Type_B    | SUPP_B         |
| 3        | C       | 3       | Type_C    | SUPP_C         |
| 4        | D       | 3       | Type_D    | SUPP_D         |
|------------------------------------------|----------------|

如果有人可以按照建议帮助修改查询以输出,我将不胜感激。因为我的理解是它应该像写的那样工作?

4

4 回答 4

5

您的问题是 Prod_Id 1 在这些日期范围之内和之外。因此,改为使用子查询来过滤掉哪些 Prod_Id 在这些范围内,并排除那些。

这是您的查询的一个非常简化的版本:

SELECT P.Prod_ID
FROM Products P 
 LEFT JOIN (
   SELECT Prod_ID 
   FROM Hires
   WHERE hire_end >= To_Date('20130121', 'yyyymmdd') AND hire_start <= To_Date('20130126', 'yyyymmdd')
   ) H ON P.Prod_ID = H.Prod_ID
WHERE h.prod_id IS NULL

还有SQL 小提琴

假设我正确复制和粘贴,这应该是您的查询:

SELECT products.prod_id, products.title, products.price, product_types.name,  
listagg(suppliers.name, ',') WITHIN GROUP(ORDER BY suppliers.name) suppliers
FROM products 
INNER JOIN product_suppliers ON products.prod_id = product_suppluer.prod_id 
INNER JOIN product_types ON product_types.type_id = products.type_id 
INNER JOIN suppliers ON product_suppliers.supp_id = suppliers.supp_id 
LEFT JOIN (
   SELECT Prod_ID 
   FROM Hires
   WHERE hire_end >= To_Date('20130121', 'yyyymmdd') AND hire_start <= To_Date('20130126', 'yyyymmdd')
   ) H ON products.Prod_ID = H.Prod_ID
WHERE H.Prod_ID IS NULL
GROUP BY products.prod_id, products.title, products.price, product_types.name

希望这可以帮助。

于 2013-01-25T17:11:39.260 回答
0

当没有匹配时,您的左外连接将返回空值,这意味着当此连接查询的结果为 Null 时,您仍然有一行(没有 HIRE 表数据):

LEFT OUTER JOIN hires ON hires.prod_id = products.prod_id 
WHERE (hires.hire_end < to_date('21-JAN-13') 
OR hires.hire_start > to_date('26-JAN-13')) 
OR hires.prod_id IS NULL

尝试从招聘表中添加一个选择(例如hire.Hire_Start)以查看这种情况,然后将其切换到内部连接,我认为您的问题将得到解决。

或者在完整查询上添加一个 WHERE 子句,例如hire.Hire_Start is not null

编辑

如果您将原始查询更改为:

SELECT hires.Hire_Start, products.prod_id, products.title, products.price, product_types.name,  
listagg(suppliers.name, ',') WITHIN GROUP(ORDER BY suppliers.name) suppliers
FROM products 
INNER JOIN product_suppliers ON products.prod_id = product_suppluer.prod_id 
INNER JOIN product_types ON product_types.type_id = products.type_id 
INNER JOIN suppliers ON product_suppliers.supp_id = suppliers.supp_id 
LEFT OUTER JOIN hires ON hires.prod_id = products.prod_id 
    WHERE (hires.hire_end < to_date('21-JAN-13') OR hires.hire_start > to_date('26- JAN-13')) 
    OR hires.prod_id IS NULL 
GROUP BY products.prod_id, products.title, products.price, product_types.name

Hire_Start 列中返回了什么?

然后,如果将其添加到 where 子句中,您会得到预期的结果:

SELECT hires.Hire_Start, products.prod_id, products.title, products.price, product_types.name,  
listagg(suppliers.name, ',') WITHIN GROUP(ORDER BY suppliers.name) suppliers
FROM products 
INNER JOIN product_suppliers ON products.prod_id = product_suppluer.prod_id 
INNER JOIN product_types ON product_types.type_id = products.type_id 
INNER JOIN suppliers ON product_suppliers.supp_id = suppliers.supp_id 
LEFT OUTER JOIN hires ON hires.prod_id = products.prod_id 
    WHERE (hires.hire_end < to_date('21-JAN-13') OR hires.hire_start > to_date('26- JAN-13')) 
    OR hires.prod_id IS NULL 
WHERE hires.Hire_Start is not null
GROUP BY products.prod_id, products.title, products.price, product_types.name

最后,完全放弃外部连接,这是否按预期工作?

SELECT hires.Hire_Start, products.prod_id, products.title, products.price, product_types.name,  
listagg(suppliers.name, ',') WITHIN GROUP(ORDER BY suppliers.name) suppliers
FROM products 
INNER JOIN product_suppliers ON products.prod_id = product_suppluer.prod_id 
INNER JOIN product_types ON product_types.type_id = products.type_id 
INNER JOIN suppliers ON product_suppliers.supp_id = suppliers.supp_id 
INNER JOIN hires ON hires.prod_id = products.prod_id 
    WHERE (hires.hire_end < to_date('21-JAN-13') OR hires.hire_start > to_date('26- JAN-13'))
GROUP BY products.prod_id, products.title, products.price, product_types.name

并注意:OR Hires.prod_ID 是否建议表明如果结果没有返回可用的雇用信息,在这种情况下,您需要编写查询更像提供的其他答案。

于 2013-01-25T17:03:38.903 回答
0

以下是一些可能对您有所帮助的代码:

SELECT L.V_PRODUCT_ID  "PROD_ID"   , L.TITLE "TITLE" , L.PRICE "PRICE"  , L.TYPE "TYPE" , S.NAME "SUPPLIERS"
FROM 

(SELECT V_PRODUCT_ID   , TITLE , PRICE , TYPE , SUPPLIER_ID FROM 

((select p.prod_id  v_product_id , p.title  TITLE , p.price PRICE  , t.type  TYPE
from products p , products_types t 
where p.type_id = t_type_id)   A 

JOIN
 (SELECT PROD_ID  VV_PRODUCT_ID  ,  SUPP_ID  SUPPLIER_ID  
FROM  PRODUCTS_SUPPLIERS)  H 

ON (A.V_PRODUCT_ID  = H.VV_PRODUCT_ID)))   L
JOIN 
SUPLLIERS  S 
ON (L.SUPPLIER_ID = S.SUPP_ID);
于 2013-03-13T16:11:41.177 回答
-3

SELECT Emp.Empid, Emp.EmpFirstName, Emp.EmpLastName, Dept.DepartmentName FROM Employee Emp INNER JOIN Department dept ON Emp.Departmentid=Dept.Departmenttid

于 2013-01-25T17:08:22.823 回答