Mysql
 sql >> база данни >  >> RDS >> Mysql

Преразпределете гласовете, като елиминирате кандидатите

Играех си.

Мисля, че използването на текущото ви оформление на данни може да се направи като:-

SELECT COALESCE(IF(vote_candidate_b IN (4,3,5), NULL, vote_candidate_b),
                IF(vote_candidate_c IN (4,3,5), NULL, vote_candidate_c),
                IF(vote_candidate_d IN (4,3,5), NULL, vote_candidate_d),
                IF(vote_candidate_e IN (4,3,5), NULL, vote_candidate_e),
                IF(vote_candidate_f IN (4,3,5), NULL, vote_candidate_f)) AS vote_candidate,
                COUNT(*)
FROM votes
WHERE vote_candidate_a = 4
GROUP BY vote_candidate;

Това е почти така, както е отговорил fancypants. Не ме интересува това, тъй като не изглежда лесно за четене и (ако количеството данни е голямо) вероятно ще бъде неефективно.

Бих бил по-склонен да разделя данните в различна структура на таблицата, с множество редове на набор от гласове, по един на кандидат. Това би било много по-лесно да се направи, ако системата е в ранните етапи на разработка (т.е. просто генерирате новите таблици).

Ако приемем, че съществуващите ви данни са настроени по следния начин:-

CREATE TABLE votes
(
    vote_id INT NOT NULL AUTO_INCREMENT,
    vote_candidate_a INT,
    vote_candidate_b INT,
    vote_candidate_c INT,
    vote_candidate_d INT,
    vote_candidate_e INT,
    vote_candidate_f INT
);

INSERT INTO votes
VALUES
(NULL, 4, 1, 6, 3, 2, 5),
(NULL, 4, 3, 1, 6, 2, 5),
(NULL, 4, 5, 6, 2, 3, 1),
(NULL, 4, 3, 1, 5, 6, 2);

моят формат може да бъде генериран по следния начин:-

CREATE TABLE vote_orders
(
    id INT NOT NULL AUTO_INCREMENT,
    vote_id INT,
    vote_order INT,
    vote_candidate INT
);

INSERT INTO vote_orders (id, vote_id, vote_order, vote_candidate)
SELECT NULL, vote_id, 1, vote_candidate_a FROM votes
UNION
SELECT NULL, vote_id, 2, vote_candidate_b FROM votes
UNION
SELECT NULL, vote_id, 3, vote_candidate_c FROM votes
UNION
SELECT NULL, vote_id, 4, vote_candidate_d FROM votes
UNION
SELECT NULL, vote_id, 5, vote_candidate_e FROM votes
UNION
SELECT NULL, vote_id, 6, vote_candidate_f FROM votes;

След това можете просто да използвате следното, за да получите гласовете. Това използва подзаявка, за да получи най-високия глас, който все още не е използван, и след това го обединява с данните.

SELECT vote_candidate, COUNT(*)
FROM vote_orders a
INNER JOIN
(
    SELECT vote_id, MIN(vote_order) AS min_vote_order
    FROM vote_orders
    WHERE vote_candidate NOT IN (4,3,5)
    GROUP BY vote_id
) b
ON a.vote_id = b.vote_id
AND a.vote_order = b.min_vote_order
INNER JOIN
(
    SELECT vote_id
    FROM vote_orders
    WHERE vote_candidate  = 4
    AND vote_order = 1
) c
ON a.vote_id = c.vote_id
GROUP BY vote_candidate

SQL цигулка тук:-

http://www.sqlfiddle.com/#!2/7d48c/10

Хибридно решение (най-лошото от двата свята!):-

SELECT vote_candidate, COUNT(*)
FROM 
(
    SELECT vote_id, 1 AS vote_order, vote_candidate_a AS vote_candidate FROM votes WHERE vote_candidate_a = 4
    UNION
    SELECT vote_id, 2, vote_candidate_b FROM votes WHERE vote_candidate_a = 4
    UNION
    SELECT vote_id, 3, vote_candidate_c FROM votes WHERE vote_candidate_a = 4
    UNION
    SELECT vote_id, 4, vote_candidate_d FROM votes WHERE vote_candidate_a = 4
    UNION
    SELECT vote_id, 5, vote_candidate_e FROM votes WHERE vote_candidate_a = 4
    UNION
    SELECT vote_id, 6, vote_candidate_f FROM votes WHERE vote_candidate_a = 4
) a
INNER JOIN
(
    SELECT vote_id, MIN(vote_order) AS min_vote_order
    FROM 
    (
        SELECT vote_id, 2 AS vote_order, vote_candidate_b AS vote_candidate FROM votes
        UNION
        SELECT vote_id, 3, vote_candidate_c FROM votes
        UNION
        SELECT vote_id, 4, vote_candidate_d FROM votes
        UNION
        SELECT vote_id, 5, vote_candidate_e FROM votes
        UNION
        SELECT vote_id, 6, vote_candidate_f FROM votes
    ) a
    WHERE vote_candidate NOT IN (4,3,5)
    GROUP BY vote_id
) b
ON a.vote_id = b.vote_id
AND a.vote_order = b.min_vote_order
GROUP BY vote_candidate;


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да сравните две колони, за да намерите несравними записи в MySQL

  2. Как да получите текущата дата и час в MySQL

  3. Вземете последния въведен идентификатор на автоматично увеличение в mysql

  4. Разделяне на стойността на mysql на неизвестен брой части

  5. Индексът (на база нула) трябва да е по-голям или равен на нула