4

以下の5つのテーブルを1つのクエリに結合するのを手伝ってくれる人はいますか?現在、以下のクエリがありますが、hiresテーブル内に同じIDを持つ2つの製品があるようには機能しないようです。すべての製品は、明らかに間違っている製品テーブルから返されます。

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値を返します。つまり、この結合クエリの結果が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

採用テーブル(例)からselectを追加して、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 に答える