2013-03-20 3 views
0
SELECT * 
FROM users 
WHERE id 
IN (2024) 
AND id NOT IN (
    SELECT user_id 
    FROM `used` 
    WHERE DATE_SUB(DATE_ADD(CURDATE() , INTERVAL 7 DAY) , INTERVAL 14 DAY) <= created) 
AND id NOT IN (
    SELECT user_id 
    FROM coupon_used 
    WHERE code = 'XXXXX') 
AND id IN (
    SELECT user_id 
    FROM accounts) 

나는 사용자 테이블에 ID가 2024이지만이 ID는 사용 된 테이블에 있습니다. 그래서이 쿼리를 실행하면 2024 개의 id도 필터링되어 표시됩니다. 특정 사용자를 선택한 쿼리를 실행 한 다음이 사용자가 사용중인 테이블에 있지 않아야한다고 필터링하도록합니다. 그러나 위의 쿼리는 나에게 욕망 결과를주지 않습니다. Desire 결과는 다음과 같은 조건으로 사용자를 선택하고자하는 것입니다. 특정 사용자를 데리고 coupon_used 테이블이 아닌 used table에 있는지 확인하십시오. 그러나 accounts 테이블에 있어야합니다.이 쿼리를 수정하고 다시 쓰는 방법은 무엇입니까?

답변

1

내가 왼쪽 배제 조건과 일반 조인 사용합니다 내포물에 가입하십시오 :

SELECT users.* 
FROM users 
INNER JOIN accounts ON accounts.user_id = users.id 
LEFT JOIN used ON used.user_id = users.id AND DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= used.created) 
LEFT JOIN coupon_used ON coupon_used.user_id = users.id AND coupon_used.code = 'XXXX' 
WHERE id IN (2024) AND used.user_id IS NULL AND coupon_used.user_id IS NULL 

나는 날짜 조작도 편집했습니다. +7 -14는 -7 일 것입니다.

1

먼저 조인을 사용하여 다음과 같이 시도해보십시오. 쉽게 읽을 수 있고 빠른

SELECT DISTINCT users.* 
FROM users 
INNER JOIN accounts ON users.id = accounts.user_id 
LEFT OUTER JOIN coupon_used ON users.id = coupon_used.user_id AND coupon_used.code = 'XXXXX' 
LEFT OUTER JOIN `used` ON users.id = `used`.user_id AND DATE_SUB(DATE_ADD(CURDATE() , INTERVAL 7 DAY) , INTERVAL 14 DAY) <= `used`.created 
WHERE id IN (2024) 
AND coupon_used.user_id IS NULL 
AND `used`.user_id IS NULL 

EDIT (MySQL의 버전에 따라)해야하는 - 단순화 날짜 확인 : -

SELECT DISTINCT users.* 
FROM users 
INNER JOIN accounts ON users.id = accounts.user_id 
LEFT OUTER JOIN coupon_used ON users.id = coupon_used.user_id AND coupon_used.code = 'XXXXX' 
LEFT OUTER JOIN `used` ON users.id = `used`.user_id AND DATE_SUB(CURDATE() , INTERVAL 7 DAY) <= `used`.created 
WHERE id IN (2024) 
AND coupon_used.user_id IS NULL 
AND `used`.user_id IS NULL 
+0

어제 전회 사용자 ID 2024가 사용 된 테이블에 한 행을 추가 했으므로 제외되어야합니다. 그러나 왜 그가 배제되지 않았는가? 이'used'에 따르면 users.id ='used'.user_id와 DATE_SUB (DATE_ADD (CURDATE(), INTERVAL 7 DAY), INTERVAL 14 DAY) <='used'가 생성되었습니다. – Akaash

+0

@Matt Busche - 동의했습니다. 내가 이너 조인을 사용했다고 생각했기 때문에 손가락 문제. 이제 해결되었습니다. Ta – Kickstart

+1

@Akaash - 그것을 제외해야합니다 (심지어 잭이 지적한 복잡한 날짜 조작 포함). 테이블 선언 및 샘플 데이터를 게시 할 수 있습니까? – Kickstart

1

계정에 JOIN을 사용하고 다른 두 테이블에는 LEFT OUTER JOIN을 사용할 것을 권장합니다. 계정의 JOIN은 계정 테이블에 있어야한다는 것을 의미합니다. LEFT OUTER JOINS는 coupon_used 및 used에서 해당 테이블에 있는지 여부에 관계없이 레코드를 반환합니다. c.user_id IS NULL로 필터링하면 해당 테이블에 레코드가 없습니다.

SELECT users.* 
FROM users 
    JOIN accounts ON users.id = accounts.user_id 
    LEFT OUTER JOIN coupon_used c ON users.id = c.user_id AND c.code = 'XXXXX' 
    LEFT OUTER JOIN `used` u ON users.id = u.user_id AND DATE_SUB(DATE_ADD(CURDATE() , INTERVAL 7 DAY) , INTERVAL 14 DAY) <= u.created 
WHERE id IN (2024) 
AND c.user_id IS NULL 
AND u.user_id IS NULL 
관련 문제