Ошибка преобразования при преобразовании значения varchar 'Collect_Date' в тип данных int - PullRequest
0 голосов
/ 14 марта 2019

Я пытаюсь применить фильтр даты к моему запросу.Я получаю это сообщение об ошибке

Не удалось выполнить преобразование при преобразовании значения varchar 'Collect_Date' в тип данных int

Вот мой код:

SELECT
    Location_ID, 
    CONVERT(Date,CONVERT(varchar(10),Collect_Month_Key,101)) as 'Collect_Date', 
    Calc_Gross_Totals, Loc_Country, 
    CONVERT(varchar(8),Collect_Month_Key)+'-'+Location_ID as 'Unique Key'
FROM 
    FT_GPM_NPM_CYCLES, 
    LU_Location, 
    LU_Loc_Country
WHERE
    LU_Location.LU_Loc_Country_Key=LU_Loc_Country.LU_Loc_Country_Key
    AND FT_GPM_NPM_CYCLES.Lu_Loc_Key= LU_Location.LU_Loc_Key
    AND Collect_Month_Key<>-1 
    AND 'Collect_Date'>=2016-1-1
ORDER BY
    Location_ID, 
    Collect_Date;

Если кто-то может помочь, это будет оценено.Я также получаю другую ошибку при попытке сделать Month(Collect_Date).Так что, если кто-нибудь знает, почему на этом я был бы признателен.Я добавил изображение с кодом и получаю результаты.

Ответы [ 3 ]

0 голосов
/ 14 марта 2019

Вот обновленный запрос, который вносит следующие изменения:

  • Как прокомментировал Роберт Шихан, вы не можете использовать псевдоним столбца набора результатов в предложении WHERE

  • Как прокомментировал Ларну, поскольку вы храните даты в виде строк, вы можете просто выполнить сравнение строк для фильтрации записей (и возврата строковых значений). При использовании этой техники вам не нужно дополнительное условие Collect_Month_Key <> -1, поскольку строка '-1 'не больше строки '20160101'.

  • использовать явные объединения вместо неявных (комментарий Гордона Линоффа) * ​​1019 *

  • Я добавил псевдонимы таблиц: они облегчают чтение запроса (и позволяют самостоятельно присоединяться к таблице ...)

  • Я бы также рекомендовал префикс всех столбцов, используемых в запросе, с их псевдонимом таблицы. Это четко указывает, из какой таблицы происходит каждый столбец, и облегчает понимание и обслуживание запроса. Примечание: если Collect_Month_Key принадлежит таблице, отличной от FT_GPM_NPM_CYCLES, вы хотите переместить условие из предложения WHERE в предложение ON соответствующего JOIN)

Запрос:

SELECT
    Location_ID, 
    Collect_Month_Key AS Collect_Date, 
    Calc_Gross_Totals, 
    Loc_Country, 
    CONVERT(varchar(8),Collect_Month_Key) + '-' + Location_ID AS Unique_Key
FROM 
    FT_GPM_NPM_CYCLES AS cyc
    INNER JOIN LU_Location AS loc
        ON cyc.Lu_Loc_Key = loc.LU_Loc_Key
    INNER JOIN LU_Loc_Country AS cty
        ON loc.LU_Loc_Country_Key = cty.LU_Loc_Country_Key
WHERE 
    Collect_Month_Key > '20160101'
ORDER BY 
    Location_ID, 
    Collect_Month_Key
0 голосов
/ 14 марта 2019

Чтобы ответить на ваш комментарий «Итак, если я не помещу collect_Date в WHERE, куда я должен поместить его для чего-то подобного в будущем?», Я предлагаю Common Table Expressions. Функционально они эквивалентны определению производной таблицы в предложении FROM, но они перемещают ее «выше», так что это больше похоже на «до», и я думаю, что они значительно облегчают чтение. Чтобы преобразовать отличное решение GMB в использование CTE:

--Leading ; because CTEs require prvious command terminated explicitly
;WITH cteWithDates as ( --cteDates becomes a virtual temporary table
    SELECT
        cyc.* --Keep all the original columns of FT_GPM_NPM_CYCLES
        , Collect_Month_Key AS Collect_Date --and add Collect_Date and Unique_Key
        , CONVERT(varchar(8),Collect_Month_Key) + '-' + Location_ID AS Unique_Key
    FROM FT_GPM_NPM_CYCLES AS cyc
) --you could add more CTEs with the following format, 
--all become available at the end
--, cteMore as (SELECT ... FROM ...)
--the first line after the closing ) has access to all CTEs, but ONLY that line
SELECT Location_ID, 
    Collect_Date, 
    Calc_Gross_Totals, 
    Loc_Country, 
    Unique_Key
FROM 
    cteWithDates AS cyc --Use the CTE as you would your original table, 
    --but the added fields are now available EVERYWHERE in your query!
        INNER JOIN LU_Location AS loc
            ON cyc.Lu_Loc_Key = loc.LU_Loc_Key
        INNER JOIN LU_Loc_Country AS cty
            ON loc.LU_Loc_Country_Key = cty.LU_Loc_Country_Key
WHERE 
    Collect_Date > '20160101' --NOW you can use CollectDate!
ORDER BY 
    Location_ID, 
    Collect_Date --And here too

Обратите внимание, что это намного эффективнее, чем определение фактической временной таблицы с помощью #TableName, поскольку оптимизатор запросов может отбрасывать неиспользуемые записи из CTE, но он должен поместить их все в таблицу #tevent, что является огромной разницей в производительности, если ваш таблица большая, а соответствующее подмножество маленькое.

0 голосов
/ 14 марта 2019

Я вижу, что происходит, вы пытаетесь использовать псевдоним в операторе выбора.Вы не можете сделать это, Есть несколько других вопросов, которые были освещены в комментариях, но вот немедленный ответ на вопрос:

Select  Location_ID 
  , Convert(Date,CONVERT(varchar(10),Collect_Month_Key,101)) as Collect_Date 
  , Calc_Gross_Totals
  , Loc_Country 
  , CONVERT(varchar(8),Collect_Month_Key)+'-'+Location_ID as [Unique Key]
From FT_GPM_NPM_CYCLES
  , LU_Location
  , LU_Loc_Country
Where LU_Location.LU_Loc_Country_Key=LU_Loc_Country.LU_Loc_Country_Key
  and FT_GPM_NPM_CYCLES.Lu_Loc_Key= LU_Location.LU_Loc_Key
  and Collect_Month_Key <> -1 
  and Convert(Date,CONVERT(varchar(10),Collect_Month_Key,101)) >= '2016-1-1'
Order By Location_ID, Collect_Date;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...