我知道有一个很好的方法可以做到这一点,但是由于某种原因,我无法想到任何方法。我需要返回用户尚未使用的可用促销代码的列表。我打算建立一个包含所有可用促销代码的临时表,然后循环遍历以建立列表,但这似乎是一个可怕的主意。到目前为止,这是我的代码:
DECLARE
@Email AS NVARCHAR(500) = ''
--AS
--BEGIN
--Build Active Promotions
SELECT
Promotion_ID AS 'ID',
Promotional_Code,
[Description]
INTO #ActivePromotions
FROM [dbo].[WBG_Promotional_Code]
WHERE
[Start_Date] < GETDATE() AND
GETDATE() < [End_Date]
--Build Count
DECLARE @Count AS INT = (SELECT COUNT(ID) FROM #ActivePromotions)
DECLARE @Tick INT = 0;
--Build List
WHILE @Count < @Tick BEGIN
SET @Tick = @Tick + 1;
END;
DROP TABLE #ActivePromotions
-END
这是购买表:
Purchase_ID,
Email,
Product_Name,
Purchase_Date,
Purchase_Amount,
Promotional_Code
这是促销代码表
Promotion_ID,
Promotional_Code,
Start_Date,
End_Date,
Description
一开始我唯一想到的就是对Promotional_Code进行LEFT联接到Purchasing来联接表,并尝试进一步过滤,但无法使它起作用。开放的想法。
答案 0 :(得分:1)
通过NOT EXISTS
关联子查询可能会比使用LEFT JOIN
获得更好的性能。
编辑:根据OP的评论和发布的答案扩展查询。
假设:“使用的代码”是来自购买表中与参数化的@Email
地址相关联的代码。
WITH usedCodes AS
(
SELECT
Email,
Promotional_Code
FROM
dbo.WBG_Purchase
WHERE
Email = @Email
GROUP BY
Email,
Promotional_Code
)
SELECT
p.Promotion_ID AS 'ID',
p.Promotional_Code,
p.[Description]
INTO #ActivePromotions
FROM dbo.WBG_Promotional_Code as p
WHERE
p.[Start_Date] < GETDATE()
AND
GETDATE() < p.[End_Date]
AND
NOT EXISTS
(SELECT 1
FROM usedCodes as uc
WHERE p.Promotional_Code = uc.Promotional_Code);
CTE将购买表中的数据集限制为与您要发送到过程中的电子邮件地址相关的购买。相关子查询在促销代码表中查找未出现在CTE数据集中的代码。
答案 1 :(得分:0)
我将建议这个答案。我尚未对其进行大量测试,但似乎可以正常工作。
SELECT
Promotion_ID AS 'ID',
Promotional_Code,
[Description]
FROM [dbo].[WBG_Promotional_Code] as c
WHERE
[Start_Date] < GETDATE() AND
GETDATE() < [End_Date] AND
Promotional_Code NOT IN (SELECT [Promotional_Code] FROM [dbo].[WBG_Purchase] as p WHERE p.Promotional_Code IS NOT NULL AND p.Email = @Email)