【问题标题】:SQL composite key querySQL 复合键查询
【发布时间】:2009-02-10 11:49:03
【问题描述】:
再次引用此SQL products/productsales
当主键由两列而不是一列组成时,我怎么能这样做?
所以 products 有两列作为 PK,productsales 有两列作为 FK。
这里是使用 1 列键的解决方案:
SELECT p.[name]
FROM products p
WHERE p.product_id in (SELECT s.product_id
FROM productsales s
WHERE s.[date] between @dateStart and @dateEnd
GROUP BY s.product_id
HAVING Sum(s.quantity) > @X )
【问题讨论】:
标签:
sql
aggregate-functions
composite-key
【解决方案1】:
按照这些思路可以工作
SELECT p.[name]
FROM products p
JOIN (SELECT s.key1, s.key2
FROM productsales s
WHERE s.[date] between @dateStart and @dateEnd
GROUP BY s.product_id
HAVING Sum(s.quantity) > @X ) as a on a.key1 = p.key1 and a.key2 = p.key2
【解决方案2】:
也许这样可以:
SELECT p.first_col_id,p.second_col_id
FROM products p
JOIN productsales s
ON s.first_col_id = p.first_col_id
AND s.second_col_id = p.second_col_id
AND s.[date] between @dateStart and @dateEnd
GROUP BY p.first_col_id,p.second_col_id
HAVING Sum(s.quantity) > @X )
【解决方案3】:
看起来上面有一些答案会起作用,但只是向您抛出另一个解决方案,以防它在您的情况下效果更好:
SELECT
P.name
FROM
Products P
WHERE
EXISTS
(
SELECT
*
FROM
ProductSales PS
WHERE
PS.product_id = P.product_id AND
PS.date BETWEEN @date_start AND @date_end
GROUP BY
PS.product_id
HAVING
SUM(PS.quantity) > @cutoff_quantity
)
这种方法的性能往往比使用 Brownstone 先生给出的 GROUP BY 方法的 INNER JOIN 更差,但在某些情况下,根据您的 @cutoff_quantity 值和表大小,它可能会表现得更好。
【解决方案4】:
试试:
SELECT p.[name]
FROM products p
WHERE (p.product_key1, p.product_key2) in
(SELECT s.product_key1, s.product_key2
FROM productsales s
WHERE s.[date] between @dateStart and @dateEnd
GROUP BY s.product_key1, s.product_key2
HAVING Sum(s.quantity) > @X )
【解决方案5】:
我喜欢这样做:
;WITH t
AS (SELECT s.product_id
FROM productsales s
WHERE s.[date] BETWEEN @dateStart AND @dateEnd
GROUP BY s.product_id
HAVING Sum(s.quantity) > @X)
SELECT p.[name]
FROM products p
JOIN t
ON p.pk1 = t.fk1
AND p.pk2 = t.fk2
【解决方案6】:
一键重构
SELECT s.product_id, p.[name]
FROM products p JOIN productsales s ON p.product_id=s.product_id
WHERE s.[date] between @dateStart and @dateEnd
GROUP BY s.product_id, p.[name]
HAVING Sum(s.quantity) > @X )
两个键相同:
SELECT s.k1, s.k2, p.[name]
FROM products p JOIN productsales s ON (p.k1=s.k1 AND p.k2=s. k2)
WHERE s.[date] between @dateStart and @dateEnd
GROUP BY s.k1, s.k2, p.[name]
HAVING Sum(s.quantity) > @X )