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,
    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使用价值最低的那个。如何仅提取该字段值最低的行?我尝试将其嵌套为子查询,但无法使其正常工作。数据库本身是完全静态的,我无法以任何方式更改架构。

4

3 回答 3

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'
于 2013-11-13T17:16:53.643 回答
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
于 2013-11-13T17:39:15.570 回答
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
于 2013-11-13T17:12:17.647 回答