提问人:ProgrammingGirly 提问时间:11/22/2022 最后编辑:ProgrammingGirly 更新时间:11/22/2022 访问量:61
SQL 匹配日期和产品
SQL Match dates and products
问:
我正在努力寻找一种在 SQL 中创建一个表的方法,在其中我可以合并所有销售日期和可用产品。我的任务是创建一个包含 2022 年 1 月 1 日至 2022 年 12 月 31 日之间的日期范围的表。
我的数据样本包括 2022 年 1 月 1 日至 2022 年 12 月 31 日之间的日期。日期表是我生成年份日期的表格,我必须使用它来匹配我的产品和销售。
CREATE TABLE Date_Table (
DateID INT IDENTITY CONSTRAINT PK_Date_Table PRIMARY KEY,
Date DATE NOT NULL,
Month TINYINT NOT NULL,
Year INT NOT NULL
);
CREATE TABLE Sales_Table (
SaleID INT IDENTITY CONSTRAINT PK_Sales_Table PRIMARY KEY,
Date_of_Sale DATE NOT NULL,
Qty_sold INT NOT NULL,
Total MONEY NOT NULL,
ProductID INT NOT NULL CONSTRAINT FK_Product_Table REFERENCES Product_table(ProductID));
);
CREATE TABLE Product_table (
ProductID INT IDENTITY CONSTRAINT PK_Product_Table PRIMARY KEY,
ProductName NVARCHAR(25) NOT NULL,
ProductNumber NVARCHAR(25) NOT NULL
);
我还没有找到一种方法来创建一个看起来像这样的表:
日期 | 产品 | “售出数量” |
---|---|---|
2022-01-01 | AB1型 | 0 |
2022-01-01 | AB2型 | 2 |
2022-01-01 | AB3型 | 1 |
2022-01-01 | AB4型 | 0 |
2022-01-01 | AB5型 | 2 |
2022-01-02 | AB1型 | 3 |
2022-01-02 | AB2型 | 1 |
2022-01-02 | AB3型 | 0 |
2022-01-02 | AB4型 | 0 |
2022-01-02 | AB5型 | 0 |
因此,我希望所有日期都与所有产品相匹配,即使没有销售。我已经为此工作了一段时间,但我似乎找不到解决方案。如果有人有一点想法可以帮助我开始,我将不胜感激
到目前为止,我只是在我的表之间进行了一些连接,希望完全连接可以让我保留所有必要的数据,但它不起作用。
答:
1赞
seanb
11/22/2022
#1
这样做的诀窍是首先创建所有行,然后才使用已售出的数量填充。
创建所有行的最简单方法是执行例如,CROSS JOIN
SELECT Date_Table.[Date], Product_Table.ProductID, Product_Table.ProductName
FROM Date_Table
CROSS JOIN Product_Table
上面将为每个产品、每个日期提供一行(因此,如果 365 个产品为 5 天,则为 365 x 5 = 1825 行)。
这样一来,您就可以使用 LEFT JOIN 将其加入到您的实际销售中,这样即使它们在销售中没有匹配项,它也会保留您的初始行。要处理空白行,请使用 ISNULL 将它们设为 0。
SELECT Date_Table.[Date], Product_Table.ProductID, Product_Table.ProductName,
ISNULL(Sales_Table.Qty_sold, 0) AS Qty_Sold
FROM (Date_Table
CROSS JOIN Product_Table)
LEFT OUTER JOIN Sales_Table ON Date_Table.[Date] = Sales_Table.[Date_of_sale]
AND Product_Table.ProductID = Sales_Table.ProductID
编辑: 下面是一个包含数据和 SQL 的 db<>fiddle 供您查看
关于数据结构设置的两点说明
- 你的PK - 我通常会尝试使PK有意义(例如,在日期表中,使用日期作为PK) - 尽管这不是必需的。但是,我建议至少在它们上放置一个非聚集索引,以便您可以直接查找日期(或产品等)。
- 我还会避免使用作为 SQL 关键字的列名,如日期、月份、年份 - 我还会考虑以更有意义的列命名,例如,不要使用“总计”,而是将其命名为“Total_Revenue”或“Total_Cost”。您的大多数字段都遵循此规则,但是......只是让你知道。
评论
0赞
ProgrammingGirly
11/22/2022
你真是太好了!非常感谢,我真的很感激。
评论
GENERATE_SERIES()
JOIN
CONSTRAINT
NULL
NOT NULL
Date_Table
DateID
Month
Year
CONSTRAINT
NULL
NOT NULL
Qty_sold
Total
ProductName
ProductNumber