2009-04-24 6 views
0

나는 2 테이블, ticket 및 ticket_custom을 가지고있다.
다음은 테이블 설정 방법입니다. alt textSQL - 중첩 된 select 문?

나는 웹 인터페이스를 사용하여 티켓 (ticket_custom 테이블의 값)을 변경할 수 있습니다. 웹 인터페이스는 원래 항목을 업데이트하는 대신 새 항목을 추가합니다.

ticket name value 
1 state Ready for Final Verification 
2 state Ready for Final Verification 
1 state Verified      

마지막 행은

그래서 쿼리를 수정해야

추가됩니다.

SELECT p.value AS __color__, 
    id AS ticket, summary, component, version, c.value AS state, milestone, t.type AS type, 
    owner, status, 
    time AS created, 
    changetime AS _changetime, description AS _description, 
    reporter AS _reporter 
    FROM ticket t, ticket_custom c 
    LEFT JOIN enum p ON p.name = t.priority AND p.type = 'priority' AND id = c.ticket 
    WHERE status <> 'closed' AND id = c.ticket 
    ORDER BY CAST(p.value AS int), milestone, t.type, time, c.ticket 

이제 쿼리에서 두 항목을 반환합니다. where 절에 중첩 된 select를 추가하려고했습니다.

SELECT g.ticket 
FROM ticket_custom g 
WHERE g.ticket = id 
ORDER BY g.ticket DESC LIMIT 1 

그래서 -

SELECT p.value AS __color__, 
    id AS ticket, summary, component, version, c.value AS state, milestone, t.type AS type, 
    owner, status, 
    time AS created, 
    changetime AS _changetime, description AS _description, 
    reporter AS _reporter 
    FROM ticket t, ticket_custom c 
    LEFT JOIN enum p ON p.name = t.priority AND p.type = 'priority' AND id = c.ticket 
    WHERE status <> 'closed' AND id = c.ticket and (
     SELECT g.ticket 
     FROM ticket_custom g 
     WHERE g.ticket = id 
     ORDER BY g.ticket DESC LIMIT 1) 
    ORDER BY CAST(p.value AS int), milestone, t.type, time, c.ticket 

분명히 내가 뭔가 잘못하고 있어요. 적어도 하나의 티켓을 가정

답변

1

대신이 작업을 수행 할 수 있습니다 :

SELECT MAX (g.ticket) FROM ticket_custom g g.ticket = ID가

당신이 그 변환 수 있지만,이 JOIN 또는 중첩 된 SELECT 등

그래서 아이디 = c.ticket 아이디 = MAX (c.ticket)

을 변경하지만 & LEFT 몇 가지 이상한 물건이 거기에있다 가입 WHERE 당신을 확인하십시오.

+0

동의합니다. 하위 쿼리를 완전히 없앨 수 있어야합니다. –

2

이 문제는 쿼리 문제보다 더 중요한 것으로 나타납니다. ticket_custom 테이블에서 하나의 레코드 만 리턴하는 것이 가능하지만 레코드가 될 레코드를 판별하는 f}은 없습니다. 샘플 표 1에서 티켓 1은 "Ready for ..."및 "Verified"값을 가졌지 만 처음 발생한 일은 표시되지 않습니다. 논리적으로, "Ready for ..."이 먼저 발생했습니다.

이 문제를 해결하는 가장 쉬운 방법은 타임 스탬프 또는 증분 ID 필드를 추가하는 것입니다. 그런 다음 하위 쿼리는 가장 최근의 항목 (최신 타임 스탬프 또는 가장 높은 ID)을 선택할 수 있습니다.

0

데이터베이스 스키마를 동적으로 만들지 마십시오 (예 : '테이블 중심'). 그것은 합리적인 디자인 패턴이 아닙니다. (나는 경험으로 알고 있습니다.) 추가 속성 작성시 약간의 노력을 아끼지 만 나중에 쿼리를 작성하고이를 실행하는 데 필요한 데이터베이스 처리에서 추가 오버 헤드가 발생합니다.

티켓 테이블에 상태 ID 열을 추가하고 상태가 변경되면 업데이트하십시오. 상태 이름을 저장할 참조 테이블을 만듭니다. 그런 다음 쿼리가 매우 간단 해지고 데이터베이스 엔진이 작은 참조 테이블에 대해 인덱싱 된 조인을 수행하는 데 필요한 노력이 줄어 듭니다.

+0

동의합니다. 삽입을 수행하는 SQL 쿼리에 액세스 할 수 없습니다. 테이블에서만 데이터를 읽을 수 있습니다. – Brad8118

+0

제레미 맞아. ticket_custom 테이블의 3 행 샘플에서 티켓 1의 현재 상태는 무엇입니까? 분명히 검증되었지만 SQL 문이 Verified가 Ready for Verification보다 높다는 것을 알기위한 ** 우아한 ** 방법은 없습니다 - CASE-WHEN 문과 관련된 매우 추악한 솔루션이 있지만 거기에 가지 않으려합니다.즉, ticket_custom 테이블에 필요한 정보가 누락되었습니다. Jeremy와 같이 타임 스탬프 또는 자동 ID를 추가하면 올바른 방향으로 나아갈 수 있습니다. –