【发布时间】:2018-10-31 10:45:00
【问题描述】:
基本上我有两张桌子。客户和采购表。我的问题是购买表非常大并导致性能问题,我正在尝试将我的代码组织到相关的 CTE 中。
我正在尝试提取购买了 A 型吉他或没有购买的人的所有购买记录。
我想过滤掉任何没有购买 GuitarType A 但仍保留没有购买任何东西的客户。
这是我的代码:
WITH Purchases AS
(
SELECT
, CustID
, GuitarType
FROM
Purchase
WHERE
GuitarType = 'A'
)
,
RelevantCustomers AS
(
SELECT
P.Custid
, P.PurchaseDate
, C.CustType
FROM
Customer
)
SELECT
Custid
, GuitarType
, PurchaseDate
FROM
Purchases AS p
INNER JOIN
RelevantCustomers AS rc ON p.CustId= rc.CustId
客户:
+--------+-------------+----------+
| CustId | CreatedDate | CustType |
+--------+-------------+----------+
| 1 | 01/01/2017 | A |
+--------+-------------+----------+
| 2 | 01/01/2018 | B |
+--------+-------------+----------+
| 4 | 01/01/2018 | C |
+--------+-------------+----------+
购买
+----------+--------------+------------+
| GuitarId | PurchaseDate | GuitarType |
+----------+--------------+------------+
| 1 | 04/01/2018 | A |
+----------+--------------+------------+
| 1 | 05/01/2018 | A |
+----------+--------------+------------+
| 1 | 06/01/2018 | C |
+----------+--------------+------------+
| 2 | 06/01/2018 | A |
+----------+--------------+------------+
| 2 | 06/01/2018 | B |
+----------+--------------+------------+
| 2 | 06/01/2018 | A |
+----------+--------------+------------+
如果我使用 INNER JOIN,那么它只会返回那些购买 Guitar Type A 的人。如果我使用 LEFT,那么它将包括所有客户。
另一种方法是将“Where GuitarType = 'A' 移至 where 子句并执行 LEFT JOIN,但这会导致我的代码杂乱无章,并可能出现一些性能问题。
【问题讨论】:
-
如果您的代码运行速度非常慢,请查看结构并添加索引,而不会使简单查询变得复杂。如果设计得当,即使有数百万行,也不应该成为问题
-
您的“当前代码”将返回错误,因为
P不是在您的第二个 CTE 的 FROM 子句中创建的,而是在 SELECT 列表中引用的。 -
@Sewder 。 . .假设如果客户购买了东西,那么
guitartype不是NULL是否合理?对于一个没有购买任何东西的客户来说,拉取购买记录是什么意思? -
我建议你尝试为 GuitatType = 'A' 选择购买并使用子查询获取客户信息,然后与所有没有购买任何东西的客户联合。另外我认为在采购表中对 CustomerID 有索引是必要的。
标签: sql-server tsql