临时列,计数和案例说明

时间:2018-10-07 23:08:47

标签: sql sql-server

我是SQL Server的新手,正在这里尝试学习绳索。我目前正在使用SQL Server Management Studio v17.9

我有两个表ProductReceipt,其中有一个共同的列(ProductID)。

我需要创建一个查询,以显示产品已售出多少次,并创建一个临时列,上面带有风味文字。

类似这样的东西:

ID          Name                 Times Sold    Movement
----------- -------------------- ------------- -------------
1           Smart TV LED 42p     1             Little Movement
27          Teatro en Casa       2             Few Movement
37          smartphone AG        0             No Movement
47          refrigerador         4             Normal Movement

我想到了这个

SELECT
    p.Idprod 'ID',
    p.name 'Product Name',
    COUNT(df.idprod) 'Times Sold',
    Movement = (CASE
                   WHEN 'Times Sold' = 0 THEN 'No Movement'
                   WHEN 'Times Sold' = 1 THEN 'Little Movement'
                   WHEN 'Times Sold' = 2 THEN 'Few Movement'
                   WHEN 'Times Sold' = 3 THEN 'Few Movement'
                   ELSE 'Normal Movement' 
                END)
FROM
    product p 
FULL JOIN 
    DetailsReciepts df ON p.IdProd = df.idProd
GROUP BY
    p.IdProd, p.name

这会显示错误消息:

  

将varchar值“已售时间”转换为数据类型int时转换失败

我尝试了Convert(),设置了@SoldTimes@Movement之类的临时语句,最后尝试了IF,但是没有运气。试图在网上搜索,我被困住了。

3 个答案:

答案 0 :(得分:0)

您无法在查询中引用计算出的列“售出时间”。您将需要创建另一个已计算“已售出时间”的表,可能是CTE,临时表或派生表。

在不了解表的情况下,您可以尝试使用CTE:

article = Article(
    name = request.POST['name'],
    rating = request.POST['rating'],
)
article.save()

有关所得到的错误的更多特定信息,“ Times Sold”只是一个字符串文字。它没有引用您要计算的列Times Times Sold。因此,当您要求case语句比较“售出的时间”是否等于一个数字时,它会尝试将“售出的时间”转换为整数,从而失败。

答案 1 :(得分:0)

您误解了这段代码在做什么:

when 'Times Sold'=3 then 'Few Movement'

您没有将COUNT(df.idprod)的值与数字进行比较。您正在将文字字符串'Times Sold'与数字进行比较。

如果您无需在case块内使用别名,那么它将起作用。

select 
    p.Idprod 'ID',
    p.name 'Product Name',
    COUNT(df.idprod) 'Times Sold',
    (case
            when COUNT(df.idprod)=0 then 'No Movement'
            when COUNT(df.idprod)=1 then 'Little Movement'
            when COUNT(df.idprod)=2 then 'Few Movement'
            when COUNT(df.idprod)=3 then 'Few Movement'
            else 'Normal Movement' 
       end ) Movement
from 
    product p FULL JOIN DetailsReciepts df 
    on p.IdProd = df.idProd
group by
    p.IdProd, 
    p.name

您可以为查询结果值分配别名,但是不能在同一查询中使用该别名。 但是,您可以在外部查询中使用别名。

这也将起作用,并且可能更可取:

select 
    subquery.ID,
    subquery.[Product Name],
    subquery.[Times Sold],
    (case
            when subquery.[Times Sold]=0 then 'No Movement'
            when subquery.[Times Sold]=1 then 'Little Movement'
            when subquery.[Times Sold]=2 then 'Few Movement'
            when subquery.[Times Sold]=3 then 'Few Movement'
            else 'Normal Movement' 
       end ) Movement
from (
     select
        p.Idprod 'ID',
        p.name 'Product Name',
        COUNT(df.idprod) 'Times Sold'
     from
       product p FULL JOIN DetailsReciepts df
        on p.IdProd = df.idProd
     group by 
        p.IdProd, p.Name
) subquery

答案 2 :(得分:0)

这是您似乎想要的查询:

select p.Idprod as id, p.name as Product_Name,
       count(df.idProd) as num_sold,
       (case when count(df.idProd) = 0 then 'No Movement'
             when count(df.idProd) = 1 then 'Little Movement'
             when count(df.idProd) <= 3 then 'Few Movement'
             else 'Normal Movement'
        end) as movement
from product p left join 
     DetailsReciepts df 
     on p.IdProd = df.idProd
group by p.IdProd, p.name;

注意:

  • full join几乎永远不适用于设计良好的数据库。您需要所有产品,因此它应该是from中的第一张表。然后使用left join
  • 请勿对列别名使用单引号。仅对日期和时间常数使用单引号。当您混淆字符串和列名时,就会遇到问题,如查询版本所示。
  • 如果需要转义列别名,请使用双引号或方括号。
  • 我建议不要为列分配混用as=<alias> =是一个SQL Server扩展;对于所有作业,我建议至少从as开始。