SQL获取模式而不是AVG

时间:2016-08-25 07:38:33

标签: sql-server tsql

我有一个存储过程,它返回产品的平均发行价格。每个问题都会有多行,因此我按条形码分组,以及为此问题插入一行的商店数量,并获得IssuePrice的平均值,因为它来自用户输入:

ALTER PROCEDURE [dbo].[GetUnknownBarcodeReport]  
@Status INT,@StoreTypeID INT
AS
BEGIN

SELECT COUNT(StoreCode) AS [# Stores]
    ,MAX(IssueName) AS IssueName
    ,AVG(IssuePrice) AS IssuePrice
    ,Barcode
    ,Product.EAN13 AS [Matched Product Code]
    ,Product.Name AS [Matched Product Name]
    ,Product.MainCatagory AS [Product Catagory]
FROM UnknownBarcodes
LEFT JOIN Product on LEFT(UnknownBarcodes.Barcode,13) = Product.EAN13
WHERE UnknownBarcodeStatusID = @Status
AND LEN(Barcode) >= 10
AND StoreTypeID = @StoreTypeID
GROUP BY Barcode, Product.EAN13, Product.Name, Product.MainCatagory
ORDER BY
    CASE WHEN @status = 1 THEN
        COUNT(StoreCode)
        WHEN @status = 2 THEN
        COUNT(StoreCode)
        WHEN @status = 3 THEN
        MAX(DateInserted)
    END DESC
 END

同一产品可以多次报告,因此有多行,但有时用户会输入不同的价格。如果十个用户都输入相同的条形码并且价格为100,那么AVG(IssuePrice)也是100.但是,如果9输入100,则最后一行输入为{{1}然后AVG变为1

我想将90.1替换为AVG的数学等价物,以便上面的示例仍然会返回MODE,因为报告的100比任何100更多其他价值。这可能在SQL中吗?

为了帮助重新创建它,该表的脚本如下:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[UnknownBarcodes](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [StoreCode] [int] NULL,
    [DateInserted] [datetime] NULL,
    [StoreTypeID] [int] NULL,
    [Barcode] [varchar](100) NULL,
    [UnknownBarcodeStatusID] [int] NULL,
    [StatusDescription] [varchar](1000) NULL,
    [IssueName] [varchar](100) NULL,
    [IssuePrice] [int] NULL,
    [AutoReported] [bit] NULL,
 CONSTRAINT [PK_UnknownBarcodes] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
SET ANSI_PADDING OFF
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Product](
    [EAN13] [bigint] NOT NULL,
    [Name] [varchar](250) NULL,
    [MainCatagory] [varchar](100) NULL,
 CONSTRAINT [PK_Product] PRIMARY KEY CLUSTERED 
(
    [EAN13] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
)
GO
SET ANSI_PADDING OFF
GO

INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (412,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',200,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (843,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (860,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (864,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (964,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (1061,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (1350,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (1375,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (1489,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)
INSERT INTO [dbo].[UnknownBarcodes] ([StoreCode],[DateInserted],[StoreTypeID],[Barcode],[UnknownBarcodeStatusID],[StatusDescription],[IssueName],[IssuePrice],[AutoReported]) VALUES (1531,2015-07-15 08:01:03.817,1,'977096171301112',3,'Scanning issues regarding the reported unknown item','ASIAN TRADER FREE TRADE',10,1)

您可以看到上述设置的模式应为10,即使一行的值200会使AVG

偏斜

3 个答案:

答案 0 :(得分:1)

来自:http://blogs.lessthandot.com/index.php/datamgmt/datadesign/calculating-mean-median-and-mode-with-sq/

模式

  

要使用sql server计算模式,我们首先需要获取集合中每个值的计数。然后,我们需要过滤数据,以便返回等于计数的值。

Declare @Temp Table(Id Int Identity(1,1), Data Decimal(10,5))

Insert into @Temp Values(1)
Insert into @Temp Values(2)
Insert into @Temp Values(5)
Insert into @Temp Values(5)
Insert into @Temp Values(5)
Insert into @Temp Values(6)
Insert into @Temp Values(6)
Insert into @Temp Values(6)
Insert into @Temp Values(7)
Insert into @Temp Values(9)
Insert into @Temp Values(10)
Insert into @Temp Values(NULL)

SELECT TOP 1 with ties DATA
FROM   @Temp
WHERE  DATA IS Not NULL
GROUP  BY DATA
ORDER  BY COUNT(*) DESC

在您的示例中,函数sql可以通过子查询来完成:

(select top 1 IssuePrice from UnknownBarcodes barx where barx.BarCode = bar.Barcode group by barx.IssuePrice order by count(*) DESC ) IssuePrice_MODE

总查询:

declare @Status int, @StoreTypeId int;
set @Status = 3;
set @StoreTypeId = 1;
SELECT 
     COUNT(bar.StoreCode) AS [# Stores]
    ,MAX(bar.IssueName) AS IssueName
    ,AVG(bar.IssuePrice) AS IssuePrice
    ,(select top 1 IssuePrice from UnknownBarcodes barx where barx.BarCode = bar.Barcode group by barx.IssuePrice order by count(*) DESC ) IssuePrice_MODE
    ,bar.Barcode
    ,Product.EAN13 AS [Matched Product Code]
    ,Product.Name AS [Matched Product Name]
    ,Product.MainCatagory AS [Product Catagory]

FROM UnknownBarcodes bar
LEFT JOIN Product on LEFT(bar.Barcode,13) = Product.EAN13
WHERE bar.UnknownBarcodeStatusID = @Status
AND LEN(bar.Barcode) >= 10
AND bar.StoreTypeID = @StoreTypeID
GROUP BY bar.Barcode, Product.EAN13, Product.Name, Product.MainCatagory
ORDER BY
    CASE WHEN @status = 1 THEN
        COUNT(bar.StoreCode)
        WHEN @status = 2 THEN
        COUNT(bar.StoreCode) 
        WHEN @status = 3 THEN
        MAX(bar.DateInserted) 
        end
     DESC

下面的查询在大型数据集上可能会更有效,因为它限制了必须迭代的结果

declare @Status int, @StoreTypeId int;
set @Status = 3;
set @StoreTypeId = 1;
with FirstQuery as (SELECT 

    *
FROM UnknownBarcodes bar
LEFT JOIN Product on LEFT(bar.Barcode,13) = Product.EAN13
WHERE bar.UnknownBarcodeStatusID = @Status
AND LEN(bar.Barcode) >= 10
AND bar.StoreTypeID = @StoreTypeID
)


select COUNT(StoreCode) AS [# Stores]
    ,MAX(IssueName) AS IssueName
    ,AVG(IssuePrice) AS IssuePrice
    ,Barcode
    ,(select top 1 IssuePrice from FirstQuery barx where barx.BarCode = FirstQuery.Barcode group by barx.IssuePrice order by count(*) DESC ) IssuePrice_MODE
    ,EAN13 AS [Matched Product Code]
    ,Name AS [Matched Product Name]
    ,MainCatagory AS [Product Catagory] 

    from FirstQuery

    GROUP BY Barcode, EAN13, Name, MainCatagory
ORDER BY
    CASE WHEN @status = 1 THEN
        COUNT(StoreCode)
        WHEN @status = 2 THEN
        COUNT(StoreCode)
        WHEN @status = 3 THEN
        MAX(DateInserted)
    END DESC

答案 1 :(得分:-1)

我使用内部查询来计算MODE。

SELECT COUNT(StoreCode) AS [# Stores]
    ,MAX(IssueName) AS IssueName
    ,AVG(IssuePrice) AS IssuePrice,
    (select top 1 issuePrice from [UnknownBarcodes] where ID = UnknownBarcodes.id group by IssuePrice having IssuePrice > 1) issuePrice_MODE
    ,Barcode
    ,Product.EAN13 AS [Matched Product Code]
    ,Product.Name AS [Matched Product Name]
    ,Product.MainCatagory AS [Product Catagory]
FROM UnknownBarcodes 
LEFT JOIN Product on LEFT(UnknownBarcodes.Barcode,13) = Product.EAN13
WHERE UnknownBarcodeStatusID = 3
AND LEN(Barcode) >= 10
AND StoreTypeID = 1
GROUP BY Barcode, Product.EAN13, Product.Name, Product.MainCatagory

答案 2 :(得分:-1)

这对你所追求的是什么有用吗?不知道它在大型数据集上的表现如何:

;with cte as
(
select count(1) over (partition by b.IssueName
                                            ,p.EAN13
                                            ,p.Name
                                            ,p.MainCatagory
                                            ) as [# Stores]
        ,b.IssueName
        ,b.IssuePrice
        ,row_number() over (partition by b.IssueName
                                            ,p.EAN13
                                            ,p.Name
                                            ,p.MainCatagory
                            order by count(1) desc
                            ) as IssuePriceSort
        ,b.Barcode
        ,p.EAN13
        ,p.Name
        ,p.MainCatagory
from UnknownBarcodes as b
    left join Product as p
        on left(b.Barcode,13) = p.EAN13
where UnknownBarcodeStatusID = @Status
      and len(Barcode) >= 10
    and StoreTypeID = @StoreTypeID
group by b.Barcode
        ,b.IssueName
        ,b.IssuePrice
        ,p.EAN13
        ,p.Name
        ,p.MainCatagory
)
select [# Stores]
    ,[IssueName]
    ,[IssuePrice]
    ,[IssuePriceSort]
    ,[Barcode]
    ,[EAN13]
    ,[Name]
    ,[MainCatagory]
from cte
where IssuePriceSort = 1
相关问题