it-swarm.com.de

SQL-Abfrage, um monatliche Verkäufe pro Produkt zu erhalten, einschließlich Produkte ohne Verkäufe

Angenommen, wir haben eine Produkttabelle (Produkt-ID, Produktname) und eine Verkaufstabelle (Produkt-ID, Datum, Menge, Menge).

Welche SQL-Abfrage würde den monatlichen Umsatz pro Produkt zurückgeben und Produkte ohne Umsatz einschließen?

(Ich benutze SQL Server, wenn das einen Unterschied macht).

Klarstellung: Ich möchte eine Zeile für jeden möglichen Monat/Produkt-Tupel. Wenn für einen bestimmten Monat/ein bestimmtes Produkt kein Umsatz erzielt wurde, sollte keine Menge/Umsatz angezeigt werden

3
Clement

Überprüfen Sie, ob Sie danach suchen (passen Sie sie nach Bedarf an):

set nocount on

--Declare a months table (or use a Date Dimension table)
Declare @Months Table (MonthNumber tinyint, MonthName varchar(20))
insert into @Months (MonthNumber,MonthName) values
(1,'January'),
(2,'February'),
(3,'March'),
(4,'April'),
(5,'May'),
(6,'June'),
(7,'July'),
(8,'August'),
(9,'September'),
(10,'October'),
(11,'November'),
(12,'December')

--Declare a products table
Declare @Products table (Id int, ProductName Varchar(20)) 
insert into @Products (Id, ProductName)
values(1,'Widgets'),(2,'Thingamabob')

Declare @Sales table (product_id int, [date] Date, qty int, amount decimal(11,2))
insert into @Sales (product_id, [date], qty, amount)
values(1,'2017-01-01',1,100.00),(2,'2017-02-01',1,200.00),(2,'2017-06-01',2,300)

--Select Months and CROSS JOIN to Products, then
--LEFT JOIN to Sales.  Use ISNULL to return zeros
--for months/products with no sales
SELECT m.MONTHNUMBER
    ,m.MonthName
    ,P.ProductName
    ,ISNULL(SUM(QTY), 0) AS QTY
    ,ISNULL(SUM(AMOUNT), 0) AS AMOUNT
FROM @Months m
CROSS JOIN @Products p
LEFT JOIN @Sales s ON DatePart(MONTH, [date]) = M.MonthNumber
    AND S.product_id = P.ID
GROUP BY m.MonthNumber
    ,m.MonthName
    ,P.ProductName
ORDER BY M.MonthNumber
    ,m.MonthName
    ,P.ProductName

| MONTHNUMBER | MonthName | ProductName | QTY | AMOUNT |
|-------------|-----------|-------------|-----|--------|
| 1           | January   | Thingamabob | 0   | 0.00   |
| 1           | January   | Widgets     | 1   | 100.00 |
| 2           | February  | Thingamabob | 1   | 200.00 |
| 2           | February  | Widgets     | 0   | 0.00   |
| 3           | March     | Thingamabob | 0   | 0.00   |
| 3           | March     | Widgets     | 0   | 0.00   |
| 4           | April     | Thingamabob | 0   | 0.00   |
| 4           | April     | Widgets     | 0   | 0.00   |
| 5           | May       | Thingamabob | 0   | 0.00   |
| 5           | May       | Widgets     | 0   | 0.00   |
| 6           | June      | Thingamabob | 2   | 300.00 |
| 6           | June      | Widgets     | 0   | 0.00   |
| 7           | July      | Thingamabob | 0   | 0.00   |
| 7           | July      | Widgets     | 0   | 0.00   |
| 8           | August    | Thingamabob | 0   | 0.00   |
| 8           | August    | Widgets     | 0   | 0.00   |
| 9           | September | Thingamabob | 0   | 0.00   |
| 9           | September | Widgets     | 0   | 0.00   |
| 10          | October   | Thingamabob | 0   | 0.00   |
| 10          | October   | Widgets     | 0   | 0.00   |
| 11          | November  | Thingamabob | 0   | 0.00   |
| 11          | November  | Widgets     | 0   | 0.00   |
| 12          | December  | Thingamabob | 0   | 0.00   |
| 12          | December  | Widgets     | 0   | 0.00   |

Anmerkung : Das OP hat nicht angegeben, dass eine Lösung gewünscht wird, die das Jahr berücksichtigt, daher wird meine Lösung nicht behandelt der Begriff eines Jahres bei der Aggregation der Daten. Wenn der Monat Januar ist (unabhängig vom Jahr), werden die Zählungen in den Januar-Eimer verschoben.

UPDATE: Zur weiteren Verdeutlichung möchte ich eine Zeile für jeden möglichen Monat/Produkt-Tupel. Wenn für einen bestimmten Monat/ein bestimmtes Produkt kein Umsatz erzielt wurde, sollte keine Menge/Umsatz angezeigt werden

4
Scott Hodgin

Dies ist, was ein LEFT JOIN tut.

Abrufen jeder Zeile aus der linken Tabelle und der übereinstimmenden Zeilen von rechts Tabelle. Für alle Zeilen der linken Tabelle, die nicht mit der rechten übereinstimmen (in Ihrem Fall für jedes Produkt ohne Umsatz), erhalten Sie NULL -Werte.

Der folgende Code:

with products (id, name) as 
(
    select 1, 'p1' union all
    select 2, 'p2' union all
    select 3, 'p3'
)
, sales (pid, date, qty, amount)  as
(
    select 1, '20170101', 3, 100  union all
    select 2, '20170101', 4, 200  union all
    select 2, '20170102', 5, 500 

)

select p.id, p.name, sales.date, sales.qty, sales.amount
from products p left join  sales on p.id = sales.pid                           
order by p.id, sales.date

Erzeugt das folgende Ergebnis:

(enter image description here

Für Produkt-ID = 3 gibt es keine Verkäufe in den Quelldaten, aber Sie sehen das Produkt weiterhin in den Ergebnissen.

BEARBEITEN:

Verwenden Sie die Kalendertabelle aus Aaron Bertrands Artikel . Sie können sich eine funktionierende Demo ansehen hier .

Sie haben eine Liste mit Monat, Produkt und Umsatz für jeden Monat des Jahres 2017 für jedes Produkt.

1
Rigerta Demiri