0

次の4つのテーブルがあります。

----------
tblDates:

DateID

30/04/2012
01/05/2012
02/05/2012
03/05/2012

----------
tblGroups:

GroupID
Home
Table

----------
tblProducts:

ProductID   GroupID
Chair       Home
Fork        Table
Knife       Table
Sofa        Home

----------
tblInventory:

DateID      ProductID   Quantity

01/05/2012  Chair       2
01/05/2012  Sofa        1
01/05/2012  Fork        10
01/05/2012  Knife       10
02/05/2012  Sofa        1
02/05/2012  Chair       3
03/05/2012  Sofa        2
03/05/2012  Chair       3

tblDates のすべての Dates 、 tblGroupsのすべてのGroupIDs、および各GroupIDの項目の合計 Quantity を返すクエリを作成しようとしています

私はこれを行うことができますが、null ではないGroupIDDateIDget Sum(Quantity)に対してのみです。代わりに0を取得したいと思います。上記のデータの例として、 の「テーブル」グループに製品のデータがないため、行を取得したいと思います。"02/05/2012 Table 0"01/05/12

私がこれまでに持っているSQLクエリは次のとおりです。

SELECT tblDates.DateID, 
       tblProducts.GroupID, 
       Sum(tblInventory.Quantity) AS SumOfQuantity
FROM (tblGroup 
     INNER JOIN tblProducts ON tblGroup.GroupID = tblProducts.GroupID) 
     INNER JOIN (tblDates INNER JOIN tblInventory ON tblDates.DateID = tblInventory.DateID) ON tblProducts.ProductID = tblInventory.ProductID
GROUP BY tblDates.DateID, tblProducts.GroupID;

私は基本的に、tblInventoryとは異なるテーブルに同じクエリを作成する必要があると考えています。これは、リストされた製品の代わりにすべての製品を行ではなく 0 でリストしますが、データベース内の日付製品の数を考えると、そうするのをためらっています。クエリが遅すぎる可能性があります。

おそらくこれを達成するためのより良い方法があります。

ありがとう

4

3 に答える 3

2

すべての可能な組み合わせを取得するにGroupsDatesCROSS JOINそれらのテーブルにアクセスする必要があります。LEFT JOIN次に、他の 2 つのテーブルに移動できます。

SELECT
    g.GroupID
  , d.DateID
  , COALESCE(SUM(i.Quantity), 0)  AS Quantity
FROM 
        tblDates  AS d
    CROSS JOIN
        tblGroups AS g
    LEFT JOIN
            tblProducts  AS p
        JOIN
            tblInventory AS i
          ON i.ProductID = p.ProductID 
      ON  p.GroupID = g.GroupID
      AND i.DateID = d.DateID 
GROUP BY
    g.GroupID
  , d.DateID
于 2012-05-03T11:20:58.607 に答える
0

どのデータベースを使用しているかはわかりませんが、私がよく知っているのは Oracle です。

明らかに、すべてのテーブルを内部結合すると、NULL を含む行は取得されません。インベントリ テーブルに外部結合を使用する場合、groupid 列が tblinventory にリストされず、1 つのテーブルにしか外部結合できないため、問題もあります。

2つの選択肢があると言えます。関数を使用するか、インベントリ テーブルに groupid 列の複製を作成します。

したがって、より良いが遅い解決策:

create or replace
function totalquantity( d date, g varchar2 ) return number as
  result number;
begin
  select nvl(sum(quantity), 0 )
  into result
  from tblinventory i, tblproducts p
  where i.productid = p.productid
  and i.dateid = d
  and p.groupid = g;
  return result;
end;

select dateid, groupid, totalquantity( dateid, groupid )
from tbldates, tblgroups

または、インベントリ テーブルに groupid 列を含める場合。(制約を使用して完全性を隔離することもできます)

select d.dateid, i.groupid, nvl(i.quantity, 0) 
from tbldates d, tblinventory i 
where i.dateid(+) = d.dateid 
group by d.dateid, g.groupid 

これが役に立てば幸いです、Gísli

于 2012-05-03T11:38:22.807 に答える
0

isnull() 関数を使用します。クエリを次のように変更します。

    SELECT tblDates.DateID, tblProducts.GroupID,
            **ISNULL( Sum(tblInventory.Quantity),0)** AS SumOfQuantity
    FROM (tblGroup INNER JOIN tblProducts ON tblGroup.GroupID = tblProducts.GroupID) 
    INNER JOIN (tblDates INNER JOIN tblInventory ON tblDates.DateID = tblInventory.DateID)
            ON tblProducts.ProductID =  tblInventory.ProductID
    GROUP BY tblDates.DateID, tblProducts.GroupID;
于 2012-05-03T11:07:22.573 に答える