假设我有一个跨三个表的多个连接的查询:
SELECT
main_data.id,
main_data.dt,
main_data.seq_num,
main_data.sale_amt,
main_data.sale_cd,
promo.promo_cd,
payment.card,
payment.priority
FROM
main_data
INNER JOIN promo
ON promo.id = main_data.id
AND main_data.dt >= promo.start_dt
AND main_data.dt <= promo_end_dt
INNER JOIN payment
ON payment.sale_cd = main_data.sale_cd
AND payment.card = main_data.card
WHERE
main_data.dt BETWEEN '2013-10-12' AND '2013-10-12'
基本上,销售额与付款方式(payment
)和促销(promo
)相关联。将促销代码映射到符合条件的付款(一对多关系)存在一些问题。
此时,main-data
可能存在重复记录。因此,我需要使用具有最低值的payment.priority
。如何仅提取该字段的最低值的行?我尝试将其嵌套为子查询,但无法使其正常工作。数据库本身是完全静态的,我无法以任何方式更改架构。
答案 0 :(得分:1)
你可以试试这个。 row_number函数通过sale_cd对PAYMENT表中的项目进行分组,然后按优先级asc对条目进行排序。因此,row_num ='1'应该为您提供按sale_cd分组的优先级的最低值。
WITH CTE AS (CARD, PRIORITY, SALE_CD, ROW_NUM)
AS
(
SELECT CARD
, PRIORITY
, SALE_CD
, ROW_NUMBER() OVER(PARTITION BY SALE_CD ORDER BY PRIORITY ASC) AS ROW_NUM
FROM PAYMENT
)
SELECT
main_data.id,
main_data.dt,
main_data.seq_num,
main_data.sale_amt,
main_data.sale_cd,
promo.promo_cd,
CTE.card,
CTE.priority
FROM
main_data
INNER JOIN promo
ON promo.id = main_data.id
AND main_data.dt >= promo.start_dt
AND main_data.dt <= promo_end_dt
INNER JOIN CTE CTE
ON CTE.sale_cd = main_data.sale_cd
AND CTE.card = main_data.card
WHERE
main_data.dt BETWEEN '2013-10-12' AND '2013-10-12'
AND CTE.ROW_NUM = '1'
答案 1 :(得分:1)
您已经提到过,作为主要属性会给出重复项,所以我假设它们是GROUP BY列
WITH A AS
(
SELECT
main_data.id,
main_data.dt,
main_data.seq_num,
main_data.sale_amt,
main_data.sale_cd,
promo.promo_cd,
payment.card,
payment.priority
, ROW_NUMBER() OVER(PARTITION BY main_data.id, main_data.dt, main_data.seq_num, main_data.sale_amt, main_data.sale_cd ORDER BY payment.priority) AS RN
FROM
main_data
INNER JOIN promo
ON promo.id = main_data.id
AND main_data.dt >= promo.start_dt
AND main_data.dt <= promo_end_dt
INNER JOIN payment
ON payment.sale_cd = main_data.sale_cd
AND payment.card = main_data.card
WHERE
main_data.dt BETWEEN '2013-10-12' AND '2013-10-12'
)
SELECT * FROM A
WHERE RN = 1
答案 2 :(得分:0)
SELECT
main_data.id,
main_data.dt,
main_data.seq_num,
main_data.sale_amt,
main_data.sale_cd,
promo.promo_cd,
payment.card,
min(payment.priority)
FROM
main_data
INNER JOIN promo
ON promo.id = main_data.id
AND main_data.dt >= promo.start_dt
AND main_data.dt <= promo_end_dt
INNER JOIN payment
ON payment.sale_cd = main_data.sale_cd
AND payment.card = main_data.card
WHERE
main_data.dt BETWEEN '2013-10-12' AND '2013-10-12'
group by main_data.id,
main_data.dt,
main_data.seq_num,
main_data.sale_amt,
main_data.sale_cd,
promo.promo_cd,
payment.card