SELECT CUST_ID, AGE_NAME FROM PM_AGET_INFO START WITH CUST_ID in (SELECT CUST_ID FROM p_act_allow_manager WHERE ACTIVITY_ID = '425') CONNECT BY PRIOR CUST_ID = FATH_CUST_ID 如何将上述返回重复行去除?
时间: 2024-02-10 09:10:40 浏览: 149
您可以使用 Oracle 中的 DISTINCT 关键字来去除重复行,示例如下:
```
SELECT DISTINCT
CUST_ID,
AGE_NAME
FROM
PM_AGET_INFO
START WITH
CUST_ID IN (
SELECT CUST_ID
FROM p_act_allow_manager
WHERE ACTIVITY_ID = '425'
)
CONNECT BY
PRIOR CUST_ID = FATH_CUST_ID;
```
另外,如果您想要在去重的同时保留某些字段的重复值,可以使用 GROUP BY 子句来实现。例如,如果您想要按照 CUST_ID 分组并计算每个分组中的行数,可以使用以下查询语句:
```
SELECT
CUST_ID,
AGE_NAME,
COUNT(*) AS ROW_COUNT
FROM
PM_AGET_INFO
WHERE
CUST_ID IN (
SELECT CUST_ID
FROM p_act_allow_manager
WHERE ACTIVITY_ID = '425'
)
GROUP BY
CUST_ID,
AGE_NAME;
```
相关问题
SELECT CUST_ID agentId, AGE_NAME agentName, countReleased, dayAmountReleased, CASE o.agelimitType WHEN '1' THEN TO_CHAR(o.agelimitNum) ELSE TO_CHAR(o.issueamtlimit) END countLimit, CASE o.agelimitType WHEN '1' THEN '不限' ELSE TO_CHAR(o.daylimitamount) END dayMaxCount FROM (SELECT m.CUST_ID, m.AGE_NAME, ad.countReleased, t.dayAmountReleased, d.daylimitamount, d.issueamtlimit, (SELECT AGE_LIMIT_NUM FROM P_ACT_ALLOW_MANAGER WHERE ACTIVITY_ID = #{activityId} AND rownum = 1 ) AS agelimitNum, (SELECT AGE_LIMIT_NUM_TYPE FROM P_ACT_MANAGER_ACTIVITY WHERE ACTIVITY_ID = #{activityId} ) AS agelimitType FROM (SELECT c1.CUST_ID, c1.AGE_NAME FROM (SELECT CUST_ID, AGE_NAME FROM PM_AGET_INFO START WITH CUST_ID = #{agetId} CONNECT BY PRIOR CUST_ID = FATH_CUST_ID ) c1 INNER JOIN (SELECT DISTINCT CUST_ID, AGE_NAME FROM PM_AGET_INFO START WITH CUST_ID in (SELECT CUST_ID FROM P_ACT_ALLOW_MANAGER WHERE ACTIVITY_ID = #{activityId} ) CONNECT BY PRIOR CUST_ID = FATH_CUST_ID ) c2 ON c1.CUST_ID = c2.CUST_ID ) m LEFT JOIN (SELECT CUST_ID, count(RECORD_ID) countReleased FROM P_ACT_MANAGER_RECORD WHERE ACTIVITY_ID = #{activityId} AND RECORD_STATUS NOT IN (2, 5) AND to_date(CREATE_TIME, 'yyyy-MM-dd hh24:mi:ss') BETWEEN to_date(#{beginTime}, 'yyyyMMddhh24miss') AND to_date(#{endTime}, 'yyyyMMddhh24miss') GROUP BY CUST_ID ) ad ON m.CUST_ID = ad.CUST_ID LEFT JOIN (SELECT AGE_ID cust_id, DAY_LIMIT_AMOUNT daylimitAmount, ISSUE_AMT_LIMIT issueAmtLimit FROM P_ACT_MANAGER_LIMIT_ALLOT WHERE ACT_ID =#{activityId} ) d ON m.CUST_ID = d.CUST_ID LEFT JOIN (SELECT CUST_ID, count(RECORD_ID) dayAmountReleased FROM P_ACT_MANAGER_RECORD WHERE ACTIVITY_ID =#{activityId} AND RECORD_STATUS NOT IN (2, 5) AND to_date(CREATE_TIME, 'yyyy-MM-dd hh24:mi:ss') BETWEEN to_date(#{todayBegin}, 'yyyyMMddhh24miss') AND to_date(#{todayend}, 'yyyyMMddhh24miss') GROUP BY CUST_ID ) t ON m.CUST_ID = t.CUST_ID) o WHERE 1 = 1 AND o.CUST_ID = #{agentId} AND o.AGE_NAME = #{agentName} ORDER BY o.countReleased DESC NULLS LAST 如何优化此段sql代码,使得更加简洁?
这段 SQL 代码可以进行以下优化:
1. 使用 WITH 子句来代替嵌套查询,增加可读性。
2. 使用 LEFT JOIN 和 COALESCE 函数来代替子查询,避免多次查询。
3. 使用 CASE WHEN THEN ELSE END 语句来代替 IF 函数。
优化后的 SQL 代码如下:
WITH
cte1 AS (
SELECT
CUST_ID,
AGE_NAME
FROM
PM_AGET_INFO
START WITH
CUST_ID = #{agetId}
CONNECT BY
PRIOR CUST_ID = FATH_CUST_ID
),
cte2 AS (
SELECT
DISTINCT CUST_ID,
AGE_NAME
FROM
PM_AGET_INFO
START WITH
CUST_ID IN (
SELECT
CUST_ID
FROM
P_ACT_ALLOW_MANAGER
WHERE
ACTIVITY_ID = #{activityId}
)
CONNECT BY
PRIOR CUST_ID = FATH_CUST_ID
),
cte3 AS (
SELECT
CUST_ID,
count(RECORD_ID) countReleased
FROM
P_ACT_MANAGER_RECORD
WHERE
ACTIVITY_ID = #{activityId}
AND RECORD_STATUS NOT IN (2, 5)
AND to_date(CREATE_TIME, 'yyyy-MM-dd hh24:mi:ss') BETWEEN to_date(#{beginTime}, 'yyyyMMddhh24miss') AND to_date(#{endTime}, 'yyyyMMddhh24miss')
GROUP BY
CUST_ID
),
cte4 AS (
SELECT
CUST_ID,
count(RECORD_ID) dayAmountReleased
FROM
P_ACT_MANAGER_RECORD
WHERE
ACTIVITY_ID =#{activityId}
AND RECORD_STATUS NOT IN (2, 5)
AND to_date(CREATE_TIME, 'yyyy-MM-dd hh24:mi:ss') BETWEEN to_date(#{todayBegin}, 'yyyyMMddhh24miss') AND to_date(#{todayend}, 'yyyyMMddhh24miss')
GROUP BY
CUST_ID
),
cte5 AS (
SELECT
AGE_LIMIT_NUM
FROM
P_ACT_ALLOW_MANAGER
WHERE
ACTIVITY_ID = #{activityId}
AND rownum = 1
),
cte6 AS (
SELECT
AGE_LIMIT_NUM_TYPE
FROM
P_ACT_MANAGER_ACTIVITY
WHERE
ACTIVITY_ID = #{activityId}
),
cte7 AS (
SELECT
AGE_ID cust_id,
DAY_LIMIT_AMOUNT daylimitAmount,
ISSUE_AMT_LIMIT issueAmtLimit
FROM
P_ACT_MANAGER_LIMIT_ALLOT
WHERE
ACT_ID =#{activityId}
)
SELECT
m.CUST_ID agentId,
m.AGE_NAME agentName,
COALESCE(ad.countReleased, 0) countReleased,
COALESCE(t.dayAmountReleased, 0) dayAmountReleased,
CASE
WHEN o.agelimitType = '1' THEN TO_CHAR(o.agelimitNum)
ELSE TO_CHAR(o.issueamtlimit)
END countLimit,
CASE
WHEN o.agelimitType = '1' THEN '不限'
ELSE TO_CHAR(o.daylimitamount)
END dayMaxCount
FROM
cte1 m
INNER JOIN cte2 c ON m.CUST_ID = c.CUST_ID AND m.AGE_NAME = c.AGE_NAME
LEFT JOIN cte3 ad ON m.CUST_ID = ad.CUST_ID
LEFT JOIN cte4 t ON m.CUST_ID = t.CUST_ID
LEFT JOIN cte5 ON 1 = 1
LEFT JOIN cte6 ON 1 = 1
LEFT JOIN cte7 d ON m.CUST_ID = d.CUST_ID
LEFT JOIN (
SELECT
COALESCE(AGE_LIMIT_NUM, 0) agelimitNum,
COALESCE(AGE_LIMIT_NUM_TYPE, '1') agelimitType
FROM
dual
) o ON 1 = 1
WHERE
m.CUST_ID = #{agentId}
AND m.AGE_NAME = #{agentName}
ORDER BY
COALESCE(ad.countReleased, 0) DESC NULLS LAST
这样可以使得代码更加简洁易读,并且避免了重复查询和嵌套查询的问题。
-- 3.使用UNION组合查询客户的编号、姓名、地址,供应商的编号、姓名、所在州。 SELECT cust_id,cust_name,cust_address FROM customers UNION SELECT vend_id,vend_name,vend_state FROM vendors;没有显示字段名
非常抱歉,我之前的回答中漏掉了一点,使用上述 SQL 语句查询结果会显示所有字段,但是不会显示字段名。如果您需要显示字段名,可以在 SQL 语句中添加别名,例如:
```
-- 使用 UNION 组合查询客户和供应商信息,并显示字段名
SELECT cust_id AS '客户编号', cust_name AS '客户姓名', cust_address AS '客户地址' FROM customers
UNION
SELECT vend_id AS '供应商编号', vend_name AS '供应商姓名', vend_state AS '供应商所在州' FROM vendors;
```
在上述 SQL 语句中,使用 AS 关键字为每个字段设置别名,这样查询结果就会显示字段名和字段值。感谢您的提醒,如果您还有其他问题,请随时向我提问。
阅读全文