Подтвердить что ты не робот

Каждое выражение GROUP BY должно содержать по крайней мере один столбец, который не является внешней ссылкой

Что я здесь делаю неправильно? Я получаю эту ошибку:

SELECT LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), 
            PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', 
            batchinfo.datapath), 8000))-1),
            qvalues.name,
            qvalues.compound,
            qvalues.rid
FROM batchinfo JOIN qvalues ON batchinfo.rowid=qvalues.rowid
WHERE LEN(datapath)>4
GROUP BY 1,2,3
HAVING rid!=MAX(rid)

Я хотел бы сгруппировать по первому, второму и третьему столбцам, имеющим максимальный размер.

Он отлично работает без группы и имеет.

4b9b3361

Ответ 1

Для начала вы не можете этого сделать:

having rid!=MAX(rid)

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

Кроме того, 1, 2, 3 недействителен в GROUP BY на SQL Server - я думаю, что он действителен только в ORDER BY.

Можете ли вы объяснить, почему это не то, что вы ищете:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound,
MAX(qvalues.rid)
 from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where LEN(datapath)>4
group by LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound

Ответ 2

Ну, как уже было сказано, вы не можете GROUP по литералам, я думаю, что вы сбиты с толку, потому что вы можете ORDER на 1, 2, 3. Когда вы используете функции в качестве столбцов, вам нужно к GROUP по тому же выражению. Кроме того, предложение HAVING неверно, вы можете использовать только то, что находится в агрегированиях. В этом случае ваш запрос должен выглядеть следующим образом:

SELECT 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound,
MAX(qvalues.rid) MaxRid
FROM batchinfo join qvalues 
ON batchinfo.rowid=qvalues.rowid
WHERE LEN(datapath)>4
GROUP BY 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound

Ответ 3

Вы не можете группировать по литералам, только столбцы.

Вероятно, вы ищете что-то вроде этого:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1) as pathinfo,
qvalues.name,
qvalues.compound,
qvalues.rid
 from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where LEN(datapath)>4
group by pathinfo, qvalues.name, qvalues.compound
having rid!=MAX(rid)

Прежде всего, вы должны дать этому первому выражению имя столбца с as. Затем вам нужно указать имена столбцов в группе по выражению.

Ответ 4

Когда вы используете GROUP BY, вам также необходимо использовать агрегатные функции для столбцов, не входящих в предложение group by.

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

select 
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000),
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
    qvalues.name,
    qvalues.compound,
    MAX(qvalues.rid)
from
    batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where
    LEN(datapath)>4
group by
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000),
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
    qvalues.name,
    qvalues.compound
having
    rid!=MAX(rid)

Edit: То, что я пытаюсь сделать здесь, это GROUP BY со всеми полями, но rid. Если это не то, что вы хотите, то, что вам нужно сделать, чтобы иметь действительный оператор SQL, добавляет вызов агрегатной функции для каждой удаленной группы по полю...

Ответ 5

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

Точка GROUP BY - это организовать вашу таблицу в секции, основанные на определенном столбце или столбцах, перед выполнением математических/агрегатных функций.

Например, в этой таблице:

Name    Age   Salary
Bob     25     20000
Sally   42     40000
John    42     90000

Оператор SELECT может иметь имя GROUP BY (Боб, Салли и Джон будут отдельными группами), Age (Bob будет одной группой, Салли и Джон будут другими) или Зарплата (почти такой же результат, что и имя).

Группирование по "1" не имеет никакого смысла, потому что "1" не является именем столбца.

Ответ 6

Вот простой запрос, чтобы найти название компании, у которой есть тип лекарства A и составляет более 2.

SELECT CNAME 
FROM COMPANY 
WHERE CNO IN (
    SELECT CNO 
    FROM MEDICINE 
    WHERE type='A' 
    GROUP BY CNO HAVING COUNT(type) > 2
)