2013-04-04 3 views
1

Нужна помощь в поиске похожих значений в базе данных SQL. Структура таблицы, как:SQL-запрос для большого размера таблицы

id   |  item_id_nm |  height | width |  length |  weight 
    ---------------------------------------------------------------------------------- 
    1   |  00000000001 |  1.0 |  1.0 |  1.0 |   1.0 
    2   |  00000000001 |  1.1 |  1.0 |  0.9 |   1.1 
    3   |  00000000001 |  2.0 |  1.0 |  1.0 |   1.0 
    4   |  00000000002 |  1.0 |  1.0 |  1.0 |   1.0 
    5   |  00000000002 |  1.0 |  1.1 |  1.1 |   1.0 
    6   |  00000000002 |  1.0 |  1.0 |  1.0 |   2.0 

идентификатор, очевидно, не может иметь дубликаты, item_id_nm может иметь дубликаты (на самом деле может происходить много раз ака> 2).

Как бы вы сформировали SQL, чтобы найти дубликаты item_id_nm, но только те, когда значения высоты, ширины, длины или веса отличаются на> 30%.

Я знаю, что ему нужно пройти через стол, но как мне сделать проверки. Спасибо за помощь.

Редактировать: Приведен пример разницы% 30. id = 3 с высотой 200% -ной разницей в 1,0 (или 1,1) идентификаторов 1 и 2. Так что извините за то, что вы не поняли, но разница 30% будет возможной для каждого значения высоты, ширины, длины или веса и если один из них имеет 30% -ную разницу, он будет считаться дубликатом других.

+0

вы можете использовать простое соединение для этого. и если вы хотите найти количество дубликатов, вы должны использовать группу по item_id_nm – bksi

+1

. От чего? Среднее значение для каждого столбца? – Wolf

+0

Просьба привести несколько строк, имеющих 30% -ную разницу, чтобы было ясно, что именно вы хотите. Вы должны дать более подробную информацию в своих вопросах, чтобы получить точные ответы. –

ответ

3

Это должно дать вам строки, отличающиеся на 30% или более от среднего значения:

SELECT t1.* 
FROM tbl t1 
INNER JOIN (
    SELECT 
     item_id_nm, 
     AVG(width) awidth, AVG(height) aheight, 
     AVG(length) alength, AVG(weight) aweight 
    FROM tbl 
    GROUP BY item_id_nm) t2 
USING (item_id_nm) 
WHERE 
    width > awidth * 1.3 OR width < awidth * 0.7 
    OR height > aheight * 1.3 OR height < aheight * 0.7 
    OR length > alength * 1.3 OR length < alength * 0.7 
    OR weight > aweight * 1.3 OR weight < aweight * 0.7 

Это один должен дать вам пары строки, отличающиеся на 30%:

SELECT t1.*,t2.* 
FROM tbl t1 
INNER JOIN tbl t2 
USING (item_id_nm) 
WHERE 
    (t1.width > t2.with * 1.3 OR t1.width < t2.width * 0.7) 
    OR (t1.height > t2.height * 1.3 OR t1.height < t2.height * 0.7) 
    OR (t1.length > t2.length * 1.3 OR t1.length < t2.length * 0.7) 
    OR (t1.weight > t2.weight * 1.3 OR t1.weight < t2.weight * 0.7) 
2

Я думаю, вы могли бы использовать что-то вроде этого:

SELECT item_id_nm 
FROM yourtable 
GROUP BY item_id_nm 
HAVING 
    MIN(height)*1.3 < MAX(height) OR 
    MIN(width)*1.3 < MAX(width) OR 
    MIN(length)*1.3 < MAX(length) OR 
    MIN(weight)*1.3 < MAX(weight) 
+1

Не забудьте HAVING COUNT (item_id_nm)> 1 –

+0

@DanLing, если count() = 1, тогда MIN() = MAX(), поэтому MIN() * 1.3 никогда не fthiella

+0

Отредактировал вопрос. – user1799107

2
SELECT 
    * 
FROM 
    TableName 
WHERE 
    (height > 1.3 * width OR height < 0.7 width) OR 
    (length > 1.3 * width OR length < 0.7 width) 
GROUP BY 
    item_id_nm 
HAVING 
    COUNT(item_id_nm) > 1 
+0

Неясно, существует ли разница в 30% между шириной и высотой, шириной и длиной той же строки ИЛИ соответствующими столбцами ширины, высоты или длины двух дубликатов. Было бы лучше, если бы были примеры в этом вопросе. –

0

Я хотел бы использовать:

SELECT s1.id AS id1, s2.id AS id2 
, s1.height AS h1, s2.height as h2 
, s1.width as width1, s2.width as width2 
, s1.length as l1, s2.length as l2 
, s1.weight as weight1, s2.weight as weight2 
FROM stack s1 
INNER JOIN stack s2 
ON s1.item_id_nm = s2.item_id_nm 
WHERE s1.id != s2.id 
AND s1.id < s2.id 
AND (abs(100-((s2.height*100)/s1.height)) > 30 
OR abs(100-((s2.width*100)/s1.width)) > 30 
OR abs(100-((s2.length*100)/s1.length)) > 30 
OR abs(100-((s2.weight*100)/s1.weight)) > 30) 

С PostgreSQL (http://sqlfiddle.com/#!12/e5f25/15). Этот код не возвращает повторяющиеся строки.

Смежные вопросы