Merge pull request #396 from Kitzanos/feature/GEPAFINBE-6429-prod
Cherry-pick (Fixed ranking issue)
This commit is contained in:
@@ -1173,26 +1173,57 @@ public class ApplicationDao {
|
|||||||
validateRankingActionRequest(rankingActionType, manualRanking);
|
validateRankingActionRequest(rankingActionType, manualRanking);
|
||||||
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
|
ApplicationEntity oldApplicationEntity = Utils.getClonedEntityForData(applicationEntity);
|
||||||
if (rankingActionType == null) {
|
if (rankingActionType == null) {
|
||||||
|
compactManualRanksAfterLeavingReposition(applicationEntity);
|
||||||
applicationEntity.setRankingActionType(null);
|
applicationEntity.setRankingActionType(null);
|
||||||
applicationEntity.setManualRanking(null);
|
applicationEntity.setManualRanking(null);
|
||||||
} else {
|
} else {
|
||||||
if (rankingActionType == ApplicationRankingActionTypeEnum.REPOSITION
|
if (rankingActionType == ApplicationRankingActionTypeEnum.REPOSITION) {
|
||||||
&& applicationRepository.existsByCallIdAndManualRankingAndIsDeletedFalseAndIdNot(
|
shiftOtherManualRanksForReposition(applicationEntity, manualRanking);
|
||||||
applicationEntity.getCall().getId(), manualRanking, applicationEntity.getId())) {
|
} else if (rankingActionType == ApplicationRankingActionTypeEnum.REMOVE) {
|
||||||
throw new CustomValidationException(Status.BAD_REQUEST,
|
compactManualRanksAfterLeavingReposition(applicationEntity);
|
||||||
Translator.toLocale(GepafinConstant.APPLICATION_RANKING_ACTION_INVALID));
|
|
||||||
}
|
}
|
||||||
applicationEntity.setRankingActionType(rankingActionType.getValue());
|
applicationEntity.setRankingActionType(rankingActionType.getValue());
|
||||||
applicationEntity.setManualRanking(
|
applicationEntity.setManualRanking(
|
||||||
rankingActionType == ApplicationRankingActionTypeEnum.REPOSITION ? manualRanking : null);
|
rankingActionType == ApplicationRankingActionTypeEnum.REPOSITION ? manualRanking : null);
|
||||||
}
|
}
|
||||||
applicationEntity = applicationRepository.save(applicationEntity);
|
applicationEntity = applicationRepository.save(applicationEntity);
|
||||||
|
normalizeDenseManualRanksForCall(applicationEntity.getCall().getId());
|
||||||
|
applicationEntity = applicationRepository.findById(applicationEntity.getId()).orElse(applicationEntity);
|
||||||
loggingUtil.addVersionHistory(
|
loggingUtil.addVersionHistory(
|
||||||
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE)
|
VersionHistoryRequest.builder().request(request).actionType(VersionActionTypeEnum.UPDATE)
|
||||||
.oldData(oldApplicationEntity).newData(applicationEntity).build());
|
.oldData(oldApplicationEntity).newData(applicationEntity).build());
|
||||||
return getApplicationResponse(applicationEntity);
|
return getApplicationResponse(applicationEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps stored manual ranks in {@code 1..N} for the call (same count as repositioned rows with a manual value),
|
||||||
|
* preserving relative order. Prevents gaps or values above the pool size (e.g. 2,3,4,5 with four apps → 1,2,3,4).
|
||||||
|
*/
|
||||||
|
private void normalizeDenseManualRanksForCall(Long callId) {
|
||||||
|
String reposition = ApplicationRankingActionTypeEnum.REPOSITION.getValue();
|
||||||
|
List<ApplicationEntity> repositioned = applicationRepository.findByCallIdAndIsDeletedFalse(callId).stream()
|
||||||
|
.filter(a -> ApplicationStatusTypeEnum.APPROVED.getValue().equals(a.getStatus()))
|
||||||
|
.filter(a -> reposition.equalsIgnoreCase(StringUtils.trimToEmpty(a.getRankingActionType())))
|
||||||
|
.filter(a -> a.getManualRanking() != null)
|
||||||
|
.sorted(Comparator.comparing(ApplicationEntity::getManualRanking).thenComparing(ApplicationEntity::getId))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (repositioned.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean changed = false;
|
||||||
|
long slot = 1L;
|
||||||
|
for (ApplicationEntity a : repositioned) {
|
||||||
|
if (!Objects.equals(a.getManualRanking(), slot)) {
|
||||||
|
a.setManualRanking(slot);
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
applicationRepository.saveAll(repositioned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public CallRankingSummaryResponse getApplicationRanking(Long callId,
|
public CallRankingSummaryResponse getApplicationRanking(Long callId,
|
||||||
List<ApplicationRankingActionTypeEnum> rankingActionTypes) {
|
List<ApplicationRankingActionTypeEnum> rankingActionTypes) {
|
||||||
CallEntity call = callRepository.findById(callId)
|
CallEntity call = callRepository.findById(callId)
|
||||||
@@ -1269,6 +1300,48 @@ public class ApplicationDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When an application stops using manual REPOSITION (cleared or REMOVE), every other manual rank above its
|
||||||
|
* old slot shifts down by one so ranks stay dense (e.g. after removing rank 1, 2 and 3 become 1 and 2).
|
||||||
|
*/
|
||||||
|
private void compactManualRanksAfterLeavingReposition(ApplicationEntity applicationEntity) {
|
||||||
|
String repositionType = ApplicationRankingActionTypeEnum.REPOSITION.getValue();
|
||||||
|
if (!repositionType.equalsIgnoreCase(StringUtils.trimToEmpty(applicationEntity.getRankingActionType()))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Long releasedRank = applicationEntity.getManualRanking();
|
||||||
|
if (releasedRank == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
applicationRepository.compactRepositionedManualRankingAfterSlotFreed(
|
||||||
|
applicationEntity.getCall().getId(),
|
||||||
|
applicationEntity.getId(),
|
||||||
|
releasedRank,
|
||||||
|
repositionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shiftOtherManualRanksForReposition(ApplicationEntity applicationEntity, Long newRank) {
|
||||||
|
Long callId = applicationEntity.getCall().getId();
|
||||||
|
Long applicationId = applicationEntity.getId();
|
||||||
|
String repositionType = ApplicationRankingActionTypeEnum.REPOSITION.getValue();
|
||||||
|
Long oldRank = applicationEntity.getManualRanking();
|
||||||
|
if (Objects.equals(oldRank, newRank)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (oldRank == null) {
|
||||||
|
applicationRepository.bumpRepositionedManualRankingFromRankInclusive(callId, applicationId, newRank,
|
||||||
|
repositionType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (newRank < oldRank) {
|
||||||
|
applicationRepository.bumpRepositionedManualRankingUpInHalfOpenInterval(callId, applicationId, newRank,
|
||||||
|
oldRank, repositionType);
|
||||||
|
} else {
|
||||||
|
applicationRepository.bumpRepositionedManualRankingDownInHalfOpenInterval(callId, applicationId, oldRank,
|
||||||
|
newRank, repositionType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets all non-terminal amendments, the application evaluation (if any), and the assigned application row to CLOSE.
|
* Sets all non-terminal amendments, the application evaluation (if any), and the assigned application row to CLOSE.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -185,4 +185,67 @@ public interface ApplicationRepository extends JpaRepository<ApplicationEntity,
|
|||||||
|
|
||||||
boolean existsByCallIdAndManualRankingAndIsDeletedFalseAndIdNot(Long callId, Long manualRanking, Long id);
|
boolean existsByCallIdAndManualRankingAndIsDeletedFalseAndIdNot(Long callId, Long manualRanking, Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments manual_ranking by 1 for other REPOSITION rows in the call with rank >= fromRank (insert / move up).
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Transactional
|
||||||
|
@Query("UPDATE ApplicationEntity a SET a.manualRanking = a.manualRanking + 1 "
|
||||||
|
+ "WHERE a.call.id = :callId AND a.isDeleted = false "
|
||||||
|
+ "AND a.rankingActionType = :repositionType "
|
||||||
|
+ "AND a.manualRanking IS NOT NULL AND a.id <> :applicationId "
|
||||||
|
+ "AND a.manualRanking >= :fromRank")
|
||||||
|
int bumpRepositionedManualRankingFromRankInclusive(@Param("callId") Long callId,
|
||||||
|
@Param("applicationId") Long applicationId,
|
||||||
|
@Param("fromRank") Long fromRank,
|
||||||
|
@Param("repositionType") String repositionType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increments manual_ranking by 1 for ranks in [lowRank, highRank) — used when moving this application to a better (smaller) rank.
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Transactional
|
||||||
|
@Query("UPDATE ApplicationEntity a SET a.manualRanking = a.manualRanking + 1 "
|
||||||
|
+ "WHERE a.call.id = :callId AND a.isDeleted = false "
|
||||||
|
+ "AND a.rankingActionType = :repositionType "
|
||||||
|
+ "AND a.manualRanking IS NOT NULL AND a.id <> :applicationId "
|
||||||
|
+ "AND a.manualRanking >= :lowRank AND a.manualRanking < :highRank")
|
||||||
|
int bumpRepositionedManualRankingUpInHalfOpenInterval(@Param("callId") Long callId,
|
||||||
|
@Param("applicationId") Long applicationId,
|
||||||
|
@Param("lowRank") Long lowRank,
|
||||||
|
@Param("highRank") Long highRank,
|
||||||
|
@Param("repositionType") String repositionType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrements manual_ranking by 1 for ranks in (lowRank, highRank] — used when moving this application to a worse (larger) rank.
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Transactional
|
||||||
|
@Query("UPDATE ApplicationEntity a SET a.manualRanking = a.manualRanking - 1 "
|
||||||
|
+ "WHERE a.call.id = :callId AND a.isDeleted = false "
|
||||||
|
+ "AND a.rankingActionType = :repositionType "
|
||||||
|
+ "AND a.manualRanking IS NOT NULL AND a.id <> :applicationId "
|
||||||
|
+ "AND a.manualRanking > :lowRank AND a.manualRanking <= :highRank")
|
||||||
|
int bumpRepositionedManualRankingDownInHalfOpenInterval(@Param("callId") Long callId,
|
||||||
|
@Param("applicationId") Long applicationId,
|
||||||
|
@Param("lowRank") Long lowRank,
|
||||||
|
@Param("highRank") Long highRank,
|
||||||
|
@Param("repositionType") String repositionType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* After this application leaves manual REPOSITION, closes the gap: every other REPOSITION row with rank
|
||||||
|
* strictly greater than {@code releasedRank} moves down by 1.
|
||||||
|
*/
|
||||||
|
@Modifying
|
||||||
|
@Transactional
|
||||||
|
@Query("UPDATE ApplicationEntity a SET a.manualRanking = a.manualRanking - 1 "
|
||||||
|
+ "WHERE a.call.id = :callId AND a.isDeleted = false "
|
||||||
|
+ "AND a.rankingActionType = :repositionType "
|
||||||
|
+ "AND a.manualRanking IS NOT NULL AND a.id <> :applicationId "
|
||||||
|
+ "AND a.manualRanking > :releasedRank")
|
||||||
|
int compactRepositionedManualRankingAfterSlotFreed(@Param("callId") Long callId,
|
||||||
|
@Param("applicationId") Long applicationId,
|
||||||
|
@Param("releasedRank") Long releasedRank,
|
||||||
|
@Param("repositionType") String repositionType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3282,4 +3282,7 @@
|
|||||||
</update>
|
</update>
|
||||||
</changeSet>
|
</changeSet>
|
||||||
|
|
||||||
|
<changeSet id="15-04-2026_RK_153423" author="Rajesh Khore">
|
||||||
|
<sqlFile dbms="postgresql" path="db/dump/update_application_ranking_view_15_04_2026.sql"/>
|
||||||
|
</changeSet>
|
||||||
</databaseChangeLog>
|
</databaseChangeLog>
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
DROP VIEW IF EXISTS application_ranking_view;
|
||||||
|
|
||||||
|
CREATE OR REPLACE VIEW application_ranking_view AS
|
||||||
|
WITH evaluation_scores AS (
|
||||||
|
SELECT
|
||||||
|
ae.application_id,
|
||||||
|
COALESCE(
|
||||||
|
SUM(
|
||||||
|
COALESCE(NULLIF(TRIM(score_item ->> 'score'), ''), '0')::numeric
|
||||||
|
),
|
||||||
|
0
|
||||||
|
) AS total_score
|
||||||
|
FROM application_evaluation ae
|
||||||
|
LEFT JOIN LATERAL jsonb_array_elements(
|
||||||
|
CASE
|
||||||
|
WHEN ae.criteria IS NULL OR BTRIM(ae.criteria) = '' THEN '[]'::jsonb
|
||||||
|
ELSE ae.criteria::jsonb
|
||||||
|
END
|
||||||
|
) score_item ON TRUE
|
||||||
|
WHERE ae.is_deleted = false
|
||||||
|
GROUP BY ae.application_id
|
||||||
|
),
|
||||||
|
approved_applications AS (
|
||||||
|
SELECT
|
||||||
|
a.id AS application_id,
|
||||||
|
a.call_id,
|
||||||
|
a.company_id,
|
||||||
|
a.user_id,
|
||||||
|
a.status AS status,
|
||||||
|
a.submission_date,
|
||||||
|
a.amount_requested,
|
||||||
|
a.amount_accepted,
|
||||||
|
a.manual_ranking,
|
||||||
|
a.ranking_action_type,
|
||||||
|
a.ndg,
|
||||||
|
a.pec_email,
|
||||||
|
c.ranking_type,
|
||||||
|
p.created_date AS protocol_datetime,
|
||||||
|
p.protocol_number AS protocol_number,
|
||||||
|
COALESCE(a.amount_accepted, a.amount_requested, 0) AS amount,
|
||||||
|
COALESCE(es.total_score, 0) AS total_score
|
||||||
|
FROM application a
|
||||||
|
JOIN call c ON c.id = a.call_id
|
||||||
|
AND (c.is_deleted = false OR c.is_deleted IS NULL)
|
||||||
|
AND NULLIF(BTRIM(c.ranking_type), '') IS NOT NULL
|
||||||
|
LEFT JOIN protocol p ON p.id = a.protocol_number
|
||||||
|
LEFT JOIN evaluation_scores es ON es.application_id = a.id
|
||||||
|
WHERE (a.is_deleted = false OR a.is_deleted IS NULL)
|
||||||
|
AND a.status = 'APPROVED'
|
||||||
|
AND COALESCE(a.ranking_action_type, '') <> 'EXCLUDE'
|
||||||
|
),
|
||||||
|
ranking_core AS (
|
||||||
|
SELECT *
|
||||||
|
FROM approved_applications
|
||||||
|
WHERE COALESCE(ranking_action_type, '') <> 'REMOVE'
|
||||||
|
),
|
||||||
|
remove_apps AS (
|
||||||
|
SELECT *
|
||||||
|
FROM approved_applications
|
||||||
|
WHERE COALESCE(ranking_action_type, '') = 'REMOVE'
|
||||||
|
),
|
||||||
|
natural_ranked AS (
|
||||||
|
SELECT
|
||||||
|
rc.*,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY rc.call_id
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN rc.ranking_type = 'SCORE' THEN rc.total_score END DESC NULLS LAST,
|
||||||
|
CASE WHEN rc.ranking_type = 'PROTOCOL_DATE_TIME' THEN rc.protocol_datetime END ASC NULLS LAST,
|
||||||
|
rc.protocol_datetime ASC NULLS LAST,
|
||||||
|
rc.application_id ASC
|
||||||
|
) AS natural_rank
|
||||||
|
FROM ranking_core rc
|
||||||
|
),
|
||||||
|
call_limits AS (
|
||||||
|
SELECT
|
||||||
|
nr.call_id,
|
||||||
|
COUNT(*)::bigint AS app_cnt,
|
||||||
|
COALESCE(
|
||||||
|
MAX(
|
||||||
|
CASE
|
||||||
|
WHEN COALESCE(nr.ranking_action_type, '') = 'REPOSITION'
|
||||||
|
AND nr.manual_ranking IS NOT NULL
|
||||||
|
THEN nr.manual_ranking
|
||||||
|
END
|
||||||
|
),
|
||||||
|
0
|
||||||
|
) AS max_manual
|
||||||
|
FROM natural_ranked nr
|
||||||
|
GROUP BY nr.call_id
|
||||||
|
),
|
||||||
|
free_ranks AS (
|
||||||
|
SELECT
|
||||||
|
cl.call_id,
|
||||||
|
gs.slot::bigint AS listing_rank,
|
||||||
|
ROW_NUMBER() OVER (PARTITION BY cl.call_id ORDER BY gs.slot) AS fill_order
|
||||||
|
FROM call_limits cl
|
||||||
|
CROSS JOIN LATERAL generate_series(
|
||||||
|
1,
|
||||||
|
GREATEST(cl.app_cnt::int, cl.max_manual::int)
|
||||||
|
) AS gs(slot)
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1
|
||||||
|
FROM natural_ranked mr
|
||||||
|
WHERE mr.call_id = cl.call_id
|
||||||
|
AND COALESCE(mr.ranking_action_type, '') = 'REPOSITION'
|
||||||
|
AND mr.manual_ranking IS NOT NULL
|
||||||
|
AND mr.manual_ranking = gs.slot
|
||||||
|
)
|
||||||
|
),
|
||||||
|
non_manual_ordered AS (
|
||||||
|
SELECT
|
||||||
|
nr.*,
|
||||||
|
ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY nr.call_id
|
||||||
|
ORDER BY
|
||||||
|
CASE WHEN nr.ranking_type = 'SCORE' THEN nr.total_score END DESC NULLS LAST,
|
||||||
|
CASE WHEN nr.ranking_type = 'PROTOCOL_DATE_TIME' THEN nr.protocol_datetime END ASC NULLS LAST,
|
||||||
|
nr.protocol_datetime ASC NULLS LAST,
|
||||||
|
nr.application_id ASC
|
||||||
|
) AS fill_order
|
||||||
|
FROM natural_ranked nr
|
||||||
|
WHERE COALESCE(nr.ranking_action_type, '') <> 'REPOSITION'
|
||||||
|
OR nr.manual_ranking IS NULL
|
||||||
|
),
|
||||||
|
manual_part AS (
|
||||||
|
SELECT
|
||||||
|
mr.call_id,
|
||||||
|
mr.application_id,
|
||||||
|
mr.ranking_action_type,
|
||||||
|
mr.total_score,
|
||||||
|
mr.user_id,
|
||||||
|
mr.status,
|
||||||
|
mr.submission_date,
|
||||||
|
mr.protocol_datetime,
|
||||||
|
mr.protocol_number,
|
||||||
|
mr.ndg,
|
||||||
|
mr.amount_accepted,
|
||||||
|
mr.pec_email,
|
||||||
|
mr.manual_ranking,
|
||||||
|
mr.ranking_type,
|
||||||
|
mr.manual_ranking AS listing_rank
|
||||||
|
FROM natural_ranked mr
|
||||||
|
WHERE COALESCE(mr.ranking_action_type, '') = 'REPOSITION'
|
||||||
|
AND mr.manual_ranking IS NOT NULL
|
||||||
|
),
|
||||||
|
non_manual_part AS (
|
||||||
|
SELECT
|
||||||
|
nmo.call_id,
|
||||||
|
nmo.application_id,
|
||||||
|
nmo.ranking_action_type,
|
||||||
|
nmo.total_score,
|
||||||
|
nmo.user_id,
|
||||||
|
nmo.status,
|
||||||
|
nmo.submission_date,
|
||||||
|
nmo.protocol_datetime,
|
||||||
|
nmo.protocol_number,
|
||||||
|
nmo.ndg,
|
||||||
|
nmo.amount_accepted,
|
||||||
|
nmo.pec_email,
|
||||||
|
nmo.manual_ranking,
|
||||||
|
nmo.ranking_type,
|
||||||
|
fr.listing_rank
|
||||||
|
FROM non_manual_ordered nmo
|
||||||
|
JOIN free_ranks fr
|
||||||
|
ON fr.call_id = nmo.call_id
|
||||||
|
AND fr.fill_order = nmo.fill_order
|
||||||
|
),
|
||||||
|
ranked_pool AS (
|
||||||
|
SELECT * FROM manual_part
|
||||||
|
UNION ALL
|
||||||
|
SELECT * FROM non_manual_part
|
||||||
|
),
|
||||||
|
pool_max AS (
|
||||||
|
SELECT call_id, COALESCE(MAX(listing_rank), 0) AS max_lr
|
||||||
|
FROM ranked_pool
|
||||||
|
GROUP BY call_id
|
||||||
|
),
|
||||||
|
remove_part AS (
|
||||||
|
SELECT
|
||||||
|
ra.call_id,
|
||||||
|
ra.application_id,
|
||||||
|
ra.ranking_action_type,
|
||||||
|
ra.total_score,
|
||||||
|
ra.user_id,
|
||||||
|
ra.status,
|
||||||
|
ra.submission_date,
|
||||||
|
ra.protocol_datetime,
|
||||||
|
ra.protocol_number,
|
||||||
|
ra.ndg,
|
||||||
|
ra.amount_accepted,
|
||||||
|
ra.pec_email,
|
||||||
|
ra.manual_ranking,
|
||||||
|
ra.ranking_type,
|
||||||
|
COALESCE(pm.max_lr, 0)
|
||||||
|
+ ROW_NUMBER() OVER (
|
||||||
|
PARTITION BY ra.call_id
|
||||||
|
ORDER BY ra.protocol_datetime ASC NULLS LAST, ra.application_id
|
||||||
|
) AS listing_rank
|
||||||
|
FROM remove_apps ra
|
||||||
|
LEFT JOIN pool_max pm ON pm.call_id = ra.call_id
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
rp.listing_rank,
|
||||||
|
rp.application_id,
|
||||||
|
rp.call_id,
|
||||||
|
rp.ranking_action_type,
|
||||||
|
rp.total_score,
|
||||||
|
rp.user_id,
|
||||||
|
rp.status,
|
||||||
|
rp.submission_date,
|
||||||
|
rp.protocol_datetime,
|
||||||
|
rp.protocol_number,
|
||||||
|
rp.ndg,
|
||||||
|
rp.amount_accepted,
|
||||||
|
rp.pec_email,
|
||||||
|
rp.manual_ranking,
|
||||||
|
rp.ranking_type
|
||||||
|
FROM ranked_pool rp
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
rv.listing_rank,
|
||||||
|
rv.application_id,
|
||||||
|
rv.call_id,
|
||||||
|
rv.ranking_action_type,
|
||||||
|
rv.total_score,
|
||||||
|
rv.user_id,
|
||||||
|
rv.status,
|
||||||
|
rv.submission_date,
|
||||||
|
rv.protocol_datetime,
|
||||||
|
rv.protocol_number,
|
||||||
|
rv.ndg,
|
||||||
|
rv.amount_accepted,
|
||||||
|
rv.pec_email,
|
||||||
|
rv.manual_ranking,
|
||||||
|
rv.ranking_type
|
||||||
|
FROM remove_part rv order by listing_rank asc;
|
||||||
Reference in New Issue
Block a user