Запрос в SQL Server 2015 дает проблемы - PullRequest
0 голосов
/ 11 июля 2019

Мой запрос в

select distinct e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date) AttDate, 
    PunchTimes = Stuff((Select ', ' + convert(varchar, d.LogDate, 8) 
                       from DeviceLogs dl WITH (NoLock) 
                        where dl.UserId = e.EmployeeId and cast(dl.LogDate as 
                        date) = cast(d.LogDate as date) for XML path('') ),1, 2, '') 
from Employees e, DeviceLogs d
where e.EmployeeId = d.UserId 
    --and cast(d.LogDate as date) between cast(@FromDate as date) and cast(@ToDate as date) 
    and cast(d.LogDate as date) between '1-Jun-2019' and '1-Jun-2019'
group by e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date)

и выдача проблемы

Сообщение 8120, уровень 16, состояние 1, строка 2 Столбец DeviceLogs.LogDate недопустим в списке выборапотому что он не содержится ни в статистической функции, ни в предложении GROUP BY.

Ответы [ 3 ]

1 голос
/ 11 июля 2019

Я рекомендую избегать group by и использовать вместо этого select distinct в подзапросе:

select e.*, 
       stuff( (select ', ' + convert(varchar(255), d.LogDate, 8) 
               from DeviceLogs dl
               where dl.UserId = e.EmployeeId and 
                     cast(dl.LogDate as date) = e.AttDate
               for XML path('')
              ), 1, 2, ''
            ) as PunchTimes
from (select distinct e.EmployeeId, e.EmployeeCode, e.EmployeeName, 
             Cast(d.LogDate as date) as AttDate
            ) 
      from Employees e join
           DeviceLogs d
           on e.EmployeeId = d.UserId 
      where d.LogDate >= '2019-06-01' and
            d.LogDate < '2019-06-02'
     ) e;

Примечание:

  • Никогда никогда не использовать запятые вFROM пункт. Всегда используйте правильный, явный, стандартный JOIN синтаксис.
  • Используйте стандартные форматы даты: 'YYYYMMDD' или 'YYYY-MM-DD'.
  • Укажите все ссылки на столбцы, если таблица ссылается на несколько таблиц.
  • Всегда используйте длину при указании VARCHAR() и подобных типов.Значение по умолчанию зависит от контекста и может привести к сложным ошибкам для отладки.
  • Используйте WITH (NOLOCK), только если вы действительно понимаете, что он делает.Я предполагаю, что вы не понимаете это полностью.
0 голосов
/ 11 июля 2019

Попробуйте это

    select distinct e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date) AttDate, 
        PunchTimes = Stuff((Select ', ' + convert(varchar, d.LogDate, 8) from DeviceLogs dl WITH (NoLock) 
            where dl.UserId = e.EmployeeId and cast(dl.LogDate as date) = cast(d.LogDate as date) for XML path('') ),1, 2, '') 
    from Employees e, DeviceLogs d
    where e.EmployeeId = d.UserId 
        --and cast(d.LogDate as date) between cast(@FromDate as date) and cast(@ToDate as date) 
        and cast(d.LogDate as date) between '1-Jun-2019' and '1-Jun-2019'
    group by e.EmployeeId, EmployeeCode, EmployeeName, AttDate

any aggregate function is not allowed in group by
0 голосов
/ 11 июля 2019

Вам необходимо добавить столбец cast(dl.LogDate as date) в предложение Group By.

ИСПРАВЛЕНИЕ: неверное прочтение раунда псевдонимов в подзапросе; проблема в том, что в подзапросе используется коррелированная ссылка на d.LogDate. Учитывая следующее DDL

CREATE TABLE Employees (EmployeeId INT PRIMARY KEY
, EmployeeCode INT
, EmployeeName VARCHAR(255))

CREATE TABLE DeviceLogs (UserId INT FOREIGN KEY REFERENCES dbo.Employees(EmployeeId), LogDate DATETIME)

Это работает: -

select distinct e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date) AttDate, 
    PunchTimes = Stuff((Select ', ' + convert(varchar, dl.LogDate, 8) 
                       from DeviceLogs dl WITH (NoLock) 
                        where dl.UserId = e.EmployeeId and cast(dl.LogDate as 
                        date) = cast(d.LogDate as date) for XML path('') ),1, 2, '') 
from Employees e, DeviceLogs d
where e.EmployeeId = d.UserId 

    and cast(d.LogDate as date) between '1-Jun-2019' and '1-Jun-2019'
group by e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date)

Но оригинальный запрос не: -

select distinct e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date) AttDate, 
    PunchTimes = Stuff((Select ', ' + convert(varchar, d.LogDate, 8) 
                       from DeviceLogs dl WITH (NoLock) 
                        where dl.UserId = e.EmployeeId and cast(dl.LogDate as 
                        date) = cast(d.LogDate as date) for XML path('') ),1, 2, '') 
from Employees e, DeviceLogs d
where e.EmployeeId = d.UserId 

    and cast(d.LogDate as date) between '1-Jun-2019' and '1-Jun-2019'
group by e.EmployeeId, EmployeeCode, EmployeeName, Cast(d.LogDate as date)
...