2012-01-04 7 views
3

мне нужно сравнить 2 столбцов в таблице и дают 3 вещи:Сравнение 2 столбцов в одной таблице

  • Число строк ПРОВЕРЕНО (Всего строк, которые были проверены)
  • количество строк, соответствующих (строки, в которых соответствовали 2 колонки)
  • граф строк различных (строки, в которых 2 колонки) различались

Мне удалось получить только совпадение строк, используя соединение, но я не уверен, как получить остальные все сразу. Важность получения всей информации в то же время заключается в том, что это очень активная таблица, и данные изменяются с большой частотой.

Я не могу опубликовать схему таблицы, так как в ней много данных, которые не имеют отношения к этой проблеме. Указанные столбцы - int(11) unsigned NOT NULL DEFAULT '0'. Для этого я назову их mask и mask_alt.

+0

Можете ли вы дать немного больше информации о том, что вы имеете в виду под «соответствием», «разными» и «проверенными»? – Bohemian

+0

, пожалуйста, разместите схему своего стола? –

+0

@johntotetwoo Я не могу, но я добавил дополнительные сведения об этом. – Jericon

ответ

4
select 
    count(*) as rows_checked, 
    sum(col = col2) as rows_matching, 
    sum(col != col2) as rows_different 
from table 

Обратите внимание на элегантный использование sum(condition).
Это работает, потому что в mysql true is 1 и false is 0. Суммируя эти подсчеты, количество случаев составляет true. Это намного более элегантный, чем case when condition then 1 else 0 end, который является эквивалентом SQL для кодирования if (condition) return true else return false; вместо простого return condition;.

+0

Попробуй это сейчас. Я ограничил его только на прошлый день. К сожалению, некоторые из столбцов, которые я должен ограничить, не индексируются, поэтому это приводит к полному сканированию таблицы около 300 М строк: S – Jericon

+0

Есть ли способ, с помощью которого можно ограничить строки изначально с помощью индексированного столбца, * затем * запустите выше. Например, если вы уверены, что лимит появляется в течение последней недели данных, сначала выберите данные за прошлую неделю в качестве внутреннего запроса с псевдонимом, а затем запросите результат этого. – Bohemian

+0

Я беру это обратно, несколько столбцов, которые я ограничивал, были проиндексированы, однако они не имели очень высокой мощности. Из строк 800M в этой таблице было проверено почти 400M. Из них было 143 М матчей. И это только результаты за последние 10 недель. – Jericon

2

Предполагая, что вы имеете в виду вы хотите подсчитать строки, в которых col1 является или не равна col2, вы можете использовать агрегат SUM() в сочетании с CASE:

SELECT 
    COUNT(*) AS total, 
    SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END)AS matching, 
    SUM(CASE WHEN col <> col2 THEN 1 ELSE 0 END) AS non_matching 
FROM table 

Это может быть более эффективным, чтобы получить общее COUNT(*) в подзапросе, хотя и использовать это значение для вычитания соответствия, чтобы получить несоответствие, если вышеуказанное недостаточно выполнено.

SELECT 
    total, 
    matching, 
    total - matching AS non_matching 
FROM 
(
    SELECT 
    COUNT(*) AS total, 
    SUM(CASE WHEN col = col2 THEN 1 ELSE 0 END)AS matching 
    FROM table 
) sumtbl 
Смежные вопросы