0

私は 2 つのデータベース テーブルを持っています。1 つは将来の日付のみで埋められたカレンダーで、もう 1 つは数量、日付、および製品 ID を持つ在庫割り当てです。

全体像は、各日付の横に単一の合計としてグループ化された在庫割り当て数量を含む日付のリストを表示するテーブルが必要だということです。

これは、7月のみの日付のカレンダーです。

CREATE TABLE `calendar` (
    `datefield` date DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

LOCK TABLES `calendar` WRITE; 

INSERT INTO `calendar` (`datefield`) VALUES 
('2012-07-01'),('2012-07-02'),('2012-07-03'),('2012-07-04'),('2012-07-05'),
('2012-07-06'),('2012-07-07'),('2012-07-08'),('2012-07-09'),('2012-07-10'),
('2012-07-11'),('2012-07-12'),('2012-07-13'),('2012-07-14'),('2012-07-15'),
('2012-07-16'),('2012-07-17'),('2012-07-18'),('2012-07-19'),('2012-07-20'), 
('2012-07-21'),('2012-07-22'),('2012-07-23'),('2012-07-24'),('2012-07-25'),
('2012-07-26'),('2012-07-27'),('2012-07-28'),('2012-07-29'),('2012-07-30'),
('2012-07-31'); 

UNLOCK TABLES;

そして、これは在庫割り当て表です。

CREATE TABLE `stock_allocation` ( 
    `ID` int(11) NOT NULL AUTO_INCREMENT, 
    `product_ID` int(11) NOT NULL,
    `date` date NOT NULL,
    `quantity` int(11) NOT NULL,
    PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

LOCK TABLES `stock_allocation` WRITE; 

INSERT INTO `stock_allocation` (`ID`, `product_ID`, `date`, `quantity`) VALUES
(1,3,'2012-07-30',50),
(2,3,'2012-07-26',40),
(3,3,'2012-07-26',100), 
(4,3,'2012-07-02',200),
(5,3,'2012-07-01',134); 

UNLOCK TABLES; 

私が実行したクエリは、必要なものに最も近いものです。

SELECT 
    calendar.datefield AS date_allocation,
    IFNULL(SUM(stock_allocation.quantity),0) AS total_allocation 
FROM 
    stock_allocation 
RIGHT JOIN 
    calendar ON DATE(stock_allocation.date) = calendar.datefield 
WHERE 
    calendar.datefield >= '2012-12-01' AND 
    calendar.datefield <='2012-12-31' 
GROUP BY 
    date_allocation

したがって、これは私が必要とするものに近い次のようなものを提供します:

    +-----------------+------------------+
    | date_allocation | total_allocation |
    +-----------------+------------------+
    | 2012-07-01      |              134 |
    | 2012-07-02      |              200 |
    | 2012-07-03      |                0 |
    | 2012-07-04      |                0 |
    | 2012-07-05      |                0 |
    | 2012-07-06      |                0 |
    | 2012-07-07      |                0 |
     etc etc
    | 2012-07-22      |                0 |
    | 2012-07-23      |                0 |
    | 2012-07-24      |                0 |
    | 2012-07-25      |                0 |
    | 2012-07-26      |              140 |
    | 2012-07-27      |                0 |
    | 2012-07-28      |                0 |
    | 2012-07-29      |                0 |
    | 2012-07-30      |               50 |
    | 2012-07-31      |                0 |
    +-----------------+------------------+

しかし、クエリを作成するために、この最後の WHERE 句を追加したいと思います。

SELECT 
    calendar.datefield AS date_allocation,
    IFNULL(SUM(stock_allocation.quantity),0) AS total_allocation 
FROM 
    stock_allocation 
RIGHT JOIN 
    calendar ON DATE(stock_allocation.date) = calendar.datefield 
WHERE 
    calendar.datefield >= '2012-07-01' AND 
    calendar.datefield <='2012-07-31' AND 
    stock_allocation.product_ID = '3' 
GROUP BY 
    date_allocation

しかし、この出力は次を返します。

    +-----------------+------------------+
    | date_allocation | total_allocation |
    +-----------------+------------------+
    | 2012-07-26      |              140 |
    | 2012-07-30      |               50 |
    +-----------------+------------------+

私が何を必要としているのか理解していただければ幸いです。サンプルの日付が含まれていることを考えると、サンプルの stock_allocation データの productID は常に 3 であるため、2 つのクエリは基本的に同じものを返すと思います。

4

4 に答える 4

1

product_id他の人が言ったように、フィルター基準をフィールドではなくフィールドに基づいて変更する必要がありIDます。

ただし、 の行の合計のみを実行しながらすべてのカレンダー日付を表示したい場合は、句の代わりに を句にproduct_id = 3追加します。そうすれば、結合がないカレンダー行は、除外されるのではなく、最終的な結果セットに保持されます (WHERE 句が行います):AND product_id = 3LEFT JOINWHEREproduct_id = 3

SELECT 
    a.datefield AS date_allocation,
    IFNULL(SUM(b.quantity),0) AS total_allocation 
FROM
    calendar a
LEFT JOIN
    stock_allocation b 
    ON a.datefield = b.date AND
       b.product_id = 3
WHERE 
    a.datefield BETWEEN '2012-07-01' AND '2012-07-31'
GROUP BY 
    a.datefield
于 2012-07-15T03:17:24.763 に答える
0

クエリが行を返さない理由は、WHERE句が、stock_allocationから一致する行がないカレンダーからすべての行を削除しているためです。そのWHERE句は、OUTER JOINを無効にし、INNERJOINのように機能させます。

ON句ではなく、句にその述語が必要ですWHERE

これにより、必要なすべてのゼロを含むすべてのカレンダー日付が取得されます。

このような:

SELECT 
    calendar.datefield AS date_allocation,
    IFNULL(SUM(stock_allocation.quantity),0) AS total_allocation 
FROM 
    stock_allocation 
RIGHT JOIN 
    calendar 
ON 
    stock_allocation.date = calendar.datefield 
    AND stock_allocation.product_ID = '3' 
WHERE 
    calendar.datefield >= '2012-07-01' AND 
    calendar.datefield <='2012-07-31' AND 
GROUP BY 
    date_allocation

注:列の周囲にDATE()関数は必要ありませんstock_allocation.date。その列のデータ型は、すでにDATEです。

于 2012-07-15T03:44:58.630 に答える
0

に変更AND stock_allocation.IDAND stock_allocation.product_IDます。

于 2012-07-15T03:06:09.367 に答える
0

stock_allocation.product_ID = '3'の代わりにすべきではありませんかstock_allocation.ID = '3'。stock_allocation.ID は常に一意です。値が「3」のエントリは 1 つだけです。

于 2012-07-15T03:09:32.397 に答える