2012-01-26 3 views
3

У меня очень настроенный SQL-запрос, который возникает у меня с проблемами. Я использую SQL-Server-2008.Пользовательский SQL GROUP BY Раздел

У меня есть только одна таблица в этом запросе, но я ищу очень конкретные данные. Требования для этого запроса:

Для каждого элемента DISTINCT PartNumber (column) мне нужно выбрать НОВЫЙ (максимальный) PO (столбец), который нужно выбрать. Однако есть еще один столбец с именем «Квитанция», где, если он содержит значение вообще, тогда PartNumber должен быть исключен вместе.

Я немного знаком с GROUP BY пунктами и футляры для выбора, но я не уверен, как связать все, что я знаю, вместе в один рабочий запрос ...

Любая помощь очень ценится! Спасибо заранее =).

ответ

4
SELECT Partnumber, MAX(PO) 
FROM MyTable t1 
WHERE NOT EXISTS (SELECT 1 
        FROM MyTable 
        WHERE (Receipt <> '0' 
         OR Receipt <> '') 
        AND Partnumber = t1.partnumber) 
GROUP BY PartNumber 

NOT EXISTS здесь исключит любую строку, которая имеет партномер, для которого квитанция заполняется в любом месте таблицы.

+0

Кажется, это лучший подход. Работает на меня! Не обращайте внимания на предыдущее изменение этого комментария. Благодаря! – ImGreg

+0

@ImGreg - Я добавил это в. Вы также можете использовать 'NOT IN', но это имеет проблемы с' NULL', как указывает Аарон в комментариях к другим ответам. – JNK

+0

Отлично. Спасибо! PartNumber «должен» никогда не быть нулевым, но лучше всего безопасным. – ImGreg

0

Edit: На основании разъяснений в комментариях, это упрощает для:

Если я вас правильно понял, то это должно сделать это:

SELECT MAX(PO) 
FROM Table 
GROUP BY PartNumber 
HAVING MAX(Receipt) = 0 

Предложение HAVING устранит PartNumber где есть даже одиночный ненулевой Receipt запись для любых строк с этим PartNumber.

+0

Я хотел бы только добавить Квитанция <> «», как если его поле, где он может быть заселен, но не гасится, может больше не NULL применимо и должно быть исключено ... Я также включил бы номер детали в список полей, если им нужно будет найти их в логических «группах», а также в шахматном порядке с помощью случайного, несвязанного номера номера P/O. – DRapp

+3

Я думаю, что это противоположность тому, что он хочет - он хочет исключить 'Partnumber', которые имеют заполненную квитанцию. Кроме того, ** 'MAX (Receipt)' НИКОГДА НЕ БУДЕТ NULL **, поскольку 'NULL' игнорируется по агрегатам по умолчанию – JNK

+0

Спасибо, я уже был в процессе исправления смысла теста. «NULL» игнорируется агрегатами, но если нет полей '' NULL' Receipt', результат 'MAX (Receipt)' фактически является «NULL» и может быть протестирован как таковой. – mwigdahl

1
SELECT MAX(PO) 
FROM aTable 
WHERE PartNumber NOT IN (
    SELECT PartNumber 
    FROM aTable 
    WHERE Receipt IS NULL 
    GROUP BY PartNumber 
    HAVING PartNumber IS NOT NULL /* fix */ 
) 
GROUP BY PartNumber 
+1

Предложите против 'NOT IN'. Хотя в этом случае может быть подразумевается/предполагается, что PartNumber не имеет значения NULL, этот запрос может возвращать непредсказуемые результаты, если PartNumber имеет значение NULL (что может быть справедливо для других читателей, рассматривающих решения по своей собственной, немного другой проблеме). Вместо этого создайте конструкцию 'НЕ СУЩЕСТВУЕТ 'или' LEFT JOIN'. –

2

Вот Анти-Join опции

SELECT t1.Partnumber, MAX(t1.PO) 
FROM MyTable t1 
    LEFT JOIN 
     (SELECT DISTINCT PartNumber From MyTable 
     WHERE COALESCE(Receipt, '') = '') t2 
    ON t1.Partnumber = t2.Partnumber 
WHERE 
    t2.Partnumber is null 
GROUP BY t1.PartNumber 
+0

Я не уверен в том, что предложение WHERE для элемента PartNumber равно null? Но это кажется правильным, кроме этого. – ImGreg

+0

@ImGreg - это исключает записи, которые соответствуют условию 'JOIN'. – JNK

+0

ohhh gotcha. хорошо, что имеет смысл! спасибо = D – ImGreg