2011-11-28 2 views
1

조건에 따라 5 개의 결과를 반환하는 쿼리를 작성하는 방법에 대한 도움이 필요합니다.
그리고이 다섯 가지 결과에서 쿼리에 지정된 경우 레코드 중 하나가 항상 나타나야합니다.
나머지는 무작위로 선택됩니다. 캐나다, 중국, 프랑스, ​​독일, 일본, 미국
나는 기록이 범주 : 자본, 랜드 마크, FLAG, 언어하나의 특정 결과 + 임의 결과로 쿼리를 작성하는 데 도움이 필요합니다.


나는 기록을 가지고 국가의 테이블 국가, 카테고리, 질문

각 질문은 CATEGORY 및 COUNTRY에 따라 분류됩니다.
이제 국가를 선택할 때마다 항상 CATEGORY "CAPITAL"이라는 질문을 항상 결과에 표시하고 싶습니다.
그래서 프랑스를 선택하면 결과 중 하나에 자본금이 있고 다른 4 개가 무작위로 선택되는 경우 프랑스에 관한 5 가지 질문을 선택해야합니다.

내 솔루션은이 개 질문을하는 것입니다하지만 난 그게 올바른 있는지 모른다 :

SELECT * FROM QUESTIONS WHERE COUNTRY = "FRANCE" AND CATEGORY = "CAPITAL" 

SELECT * FROM QUESTIONS WHERE COUNTRY = "FRANCE" AND CATEGORY != "CAPITAL" ORDER BY RAND() LIMIT 4 

후 바로 결과를 추가합니다.
나는 임의의 레코드를 선택할 수 있기 전에 레코드를 정렬해야하기 때문에 RAND() 함수를 사용하는 것이 단점을 가지고 있다고 들었습니다. 따라서 수천 개의 레코드가있는 경우에는 사용하지 않는 것이 좋습니다.
이렇게 할 수있는 더 좋은 방법이 있다면 누구든지 도울 수 있다면 많이 고맙게 생각합니다.
미리 감사드립니다.

답변

1

이 당신이 가진 것과 매우 유사하지만, 나에게 잘 보이는 :

Select * from Colors where ColorName = 'Green' 
UNION 
SELECT * FROM (Select * from Colors where ColorName != 'Green' order by Rand() limit 4) 
2

왜 그냥 그 행이 더 높은 우선 순위를 나타 내기 위해 다른 열을 추가?

Select * from Colors order by priority DESC, Rand() limit 5 

또는 매우 특정 조건이있는 경우

, 당신은이처럼 코딩 할 수 있습니다

내가 같은 솔루션을 제안 유지

SELECT * FROM Colors 
ORDER BY IF(ColorName = 'Green', 100, IF(_other_conds_if_any_, 99, 0)) DESC, 
    Rand() 
LIMIT 5 

업데이트. 좋아, 조금 더 자세히 설명하려고 노력할 것이다. 가장 좋은 IMO는 테이블에 "끈적"한 열을 추가하는 것입니다 (귀하의 경우는 QUESTIONS 임).

ALTER TABLE `QUESTIONS` ADD COLUMN `sticky` TINYINT NOT NULL DEFAULT 0; 

그런 다음 필요로 표시 한 질문에 (그것을 위해 관리자 UI를하거나 그냥 원시 쿼리를 직접 실행) 다음

UPDATE `QUESTIONS` SET `sticky` = IF(`CATEGORY` = "CAPITAL", 1, 0); 

과 같은 질문을 선택 끈적 :

SELECT * 
FROM `QUESTIONS` 
WHERE `COUNTRY` = "FRANCE" 
ORDER BY `sticky` DESC, RAND() 
LIMIT 5; 

그것은 것을 어떤 질문이 끈적한 지에 대한 조건을 지정하는 관리자 UI를 만들고, 질문을 추가 한 후에 실행하는 것이 가장 좋습니다.잦은 선택에 좋습니다. 새로운 질문이 빈번히 추가되는 경우 ORDER 절에 조건을 직접 입력하거나 (해당 열을 추가 할 필요가 없음) 조건 열을 범주 테이블에 직접 추가하고 조인하는 것이 좋습니다.

#1. don't add any column and put condition into ORDER clause 
SELECT * 
FROM `QUESTIONS` 
WHERE `COUNTRY` = "FRANCE" 
ORDER BY IF(`CATEGORY` = "CAPITAL", 1, 0) DESC, RAND() 
LIMIT 5; 

#2. add column to categories table 
SELECT q.* 
FROM `QUESTIONS` q 
    INNER JOIN `CATEGORIES` cat ON (cat.`CATEGORY_NAME` = q.`CATEGORY`) 
    #unsure what your conditions would be here as Idon't know your DB structure 
WHERE q.`COUNTRY` = "FRANCE" 
ORDER BY cat.sticky DESC, RAND() 
LIMIT 5; 
+0

+1, 이것이 가장 효율적인 해결책이라고 생각합니다. – Pateman

+0

특히 '녹색'은 아닙니다. 질의에있는 한 다른 색상이 될 수 있습니다. 결과에 4 개의 임의 색상을 사용해야합니다. – user949000

+0

@ user949000 그런 다음 제안 된 첫 번째 옵션에 대해 말합니다. 행의 "고정"상태를 나타내는 열을 추가하십시오 . 관리 측에서 열의 기본값은 0이며, 1 이상의 고정 행을 계획하는 경우 1로 설정할 수 있습니다. – Slava

0

또 다른 방법은 쿼리의 CASE 문이 될 것입니다 :

SELECT *, 
    CASE ColorName 
    WHEN 'green' THEN 2 
    ELSE RAND() 
    END AS r 
FROM Colors ORDER BY r DESC LIMIT 5 

그러나 나는 두 개의 쿼리를 수행하는 것은 실제로 빠르다는 것을 생각한다.

관련 문제