Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用自定义分页优化搜索SQL_C#_Asp.net_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

C# 使用自定义分页优化搜索SQL

C# 使用自定义分页优化搜索SQL,c#,asp.net,sql,sql-server,sql-server-2008,C#,Asp.net,Sql,Sql Server,Sql Server 2008,使用asp.net mvc应用程序和c#。我们正在做一个搜索页面 更新了我的答案。请参见下面我自己的答案并提出建议 不幸的是,select into在sql azure中不起作用 帮帮我 我有下表来显示我的项目搜索结果 项目表 ITEMID、SHOPID、ITEMNAME、描述、价格、CATID 工作台 SHOPId,标题,城市ID,活动 城市表 CITYID、CITYName、REGIONID、CountryISO 类别表 CATID,CATNAME 这是我的搜索查询,它给出给

使用asp.net mvc应用程序和c#。我们正在做一个搜索页面

更新了我的答案。请参见下面我自己的答案并提出建议


不幸的是,select into在sql azure中不起作用

帮帮我

我有下表来显示我的项目搜索结果

项目表

  • ITEMID、SHOPID、ITEMNAME、描述、价格、CATID
工作台

  • SHOPId,标题,城市ID,活动
城市表

  • CITYID、CITYName、REGIONID、CountryISO
类别表

  • CATID,CATNAME
这是我的搜索查询,它给出给定条件的分页结果

DECLARE @unitItems INT=20
DECLARE @sortOrder INT=0
DECLARE @catId INT
DECLARE @search NVARCHAR (100)=''
DECLARE @REGIONID INT=0
DECLARE @cityId INT=0
DECLARE @maxPrice DECIMAL (10, 2)
DECLARE @page INT
DECLARE @currentDate DATETIME2 (0)
set @unitItems=20
set @catId=0
set @sortOrder=0
set @search=''
set @cityId=1
set @maxPrice=0
set @page=1
set @currentDate='2013-02-24 13:14:58.073'

;WITH itemresult AS (
  SELECT IT.ITEMID, IT.ITEMNAME, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, C.CATNAME AS CATNAME,S.HEADER AS SHOPHEADER,CI.CITYNAME AS CITY, 
  ROW_NUMBER() OVER (ORDER BY IT.SHOWDATE DESC) AS RowNumber
  FROM ITEM AS IT INNER JOIN SHOP AS S ON IT.SHOPId = S.ShopId 
  INNER JOIN CITY AS CI ON CI.CITYID = S.CITYID
  INNER JOIN COUNTRY AS CY ON CI.COUNTRYISO = CY.COUNTRYISO 
  INNER JOIN REGION AS R ON CI.REGIONID = R.REGIONID 
  INNER JOIN CITY AS CI2 ON CI2.CITYID = @cityId 
  INNER JOIN CATEGORY AS C ON IT.CATID = C.CATID    

  WHERE S.ACTIVE = 1   

  GROUP BY IT.ITEMID, IT.ITEMNAME, IT.HEADER, IT.DESCRIPTION, IT.PRICE, 
  IT.CATID, IT.SHOWDATE,S.HEADER,C.CATNAME,CI.CITYNAME) 

  SELECT IT.*, CEILING(CAST(RN AS float) / @unitItems) AS UNITPAGES, RN AS UNITROWS 
  FROM itemresult IT 
  INNER JOIN (SELECT Max(RowNumber) AS RN FROM itemresult) SUBQ ON 1=1 
  WHERE IT.RowNumber BETWEEN (@page - 1) * @unitItems + 1 
  AND @unitItems * @page 
问题:

现在的问题是我们正在UI中添加新的更改。搜索UI现在将显示如下内容

第一个结果集-->假设总共找到230条记录

在Fiddle中看到的搜索结果

第二个结果集-->230条记录的不同类别和计数

CatId、CatName、TotalCountInSearch

例:1本书25和2本体育43和8其他52。 显示我可以在UI中显示如下内容

  • 所有类别(120)
  • 书籍(25)
  • 体育(43)
  • 其他(52)
和第三个结果集-->不同的城市&从230个记录中计数

CityId、CityName、TotalCountInSearch

用于在UI中显示以下内容

  • 所有城市(10)
  • 钦奈(4)
  • 班格罗(3)
  • 其他(3)
如何检索这些计数和名称,如所有类别、书籍、, 所有城市等?欢迎提供任何帮助或建议

我想根据搜索条件获得这些计数。希望将此作为我程序中的另一个结果集检索

主更新:

我在这里上传了所有的模式和实际的动态查询


这是基于类别检索计数

select 'All categories' catname, count(*) catcount from itemtable
union all
select catname, count(catid) catcount
from itemtable inner join categorytable on categorytable.catid = itemtable.catid
group by catname

这是基于城市检索计数

select 'All cities' cityname, count(*) catcount from itemtable
union all
select cityname, count(catid) catcount 
from itemtable inner join shoptable on itemtable.shopid = shoptable.shopid
inner join citytable on citytable.cityid = shoptable.cityid
group by cityname

试试这个。我希望这能满足你的期望

CREATE VIEW vSequence AS
WITH itemresult AS (
  SELECT IT.ITEMID, IT.ITEMNAME, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, C.CATNAME AS CATNAME,S.HEADER AS SHOPHEADER,CI.CITYNAME AS CITY,CI.CITYID,
  ROW_NUMBER() OVER (ORDER BY IT.SHOWDATE DESC) AS RowNumber
  FROM ITEM AS IT INNER JOIN SHOP AS S ON IT.SHOPId = S.ShopId
  INNER JOIN CITY AS CI ON CI.CITYID = S.CITYID
  INNER JOIN COUNTRY AS CY ON CI.COUNTRYISO = CY.COUNTRYISO
  INNER JOIN REGION AS R ON CI.REGIONID = R.REGIONID
  INNER JOIN CITY AS CI2 ON CI2.CITYID = 1
  INNER JOIN CATEGORY AS C ON IT.CATID = C.CATID

  WHERE S.ACTIVE = 1

  GROUP BY IT.ITEMID, IT.ITEMNAME, IT.HEADER, IT.DESCRIPTION, IT.PRICE,
  IT.CATID, IT.SHOWDATE,S.HEADER,C.CATNAME,CI.CITYNAME,CI.CITYID)

SELECT * FROM itemresult IT

GO

  SELECT IT.*, CEILING(CAST(RN AS float) / 20) AS UNITPAGES, RN AS UNITROWS
  FROM vSequence IT
  INNER JOIN (SELECT Max(RowNumber) AS RN FROM vSequence) SUBQ ON 1=1
  WHERE IT.RowNumber BETWEEN (1 - 1) * 20 + 1
  AND 20 * 1
GO
SELECT  IT.CATID,RS.CATNAME , CONVERT(varchar(10), SUM(CASE WHEN IT.CATID = CAT.CATID THEN 1 ELSE 0 END)) AS 'Count'
FROM vSequence RS INNER JOIN ITEM IT ON RS.CATID = IT.CATID
INNER JOIN CATEGORY CAT
ON IT.CATID = CAT.CATID GROUP BY IT.CATID,RS.CATNAME
GO
SELECT  CIT.CITYID,CITYNAME,CONVERT(varchar(10), SUM(CASE WHEN CIT.REGIONID =  REG.REGIONID THEN 1 ELSE 0 END)) AS 'Count'
FROM COUNTRY CON INNER JOIN REGION REG
ON CON.COUNTRYISO = REG.COUNTRYISO
INNER JOIN CITY CIT ON CIT.REGIONID =  REG.REGIONID
INNER JOIN  vSequence RS ON CIT.CITYID=RS.CITYID GROUP BY REG.REGIONID,CITYNAME, CIT.CITYID

示例。

我从您的评论中了解到,我认为您需要的是通过执行单个存储过程来获得
3个结果集。您还想知道查询是否得到优化

我认为您的vSequence
视图
现在还不错(因此,我不会在这里添加我的答案)。您需要的是
创建一个存储过程
,以使用视图获得三个不同的结果集
,如下所示。我将您在fiddle中声明的变量列表作为存储过程的参数。我在每个变量旁边都做了注释。由于您的过滤要求不明确,我将其保留为现有的

CREATE PROCEDURE myStoredProcedure 
   @unitItems INT=20, --number of items per page
   @sortOrder INT=0, --not used
   @catId INT, --not in use 
   @search NVARCHAR (100)='', --not used
   @REGIONID INT=0, -- not used
   @cityId INT=0, -- not used
   @maxPrice DECIMAL (10, 2), -- not used
   @page INT, --page number
   @currentDate DATETIME2 (0) -- not used
AS 
BEGIN

    /*
      Query 1
      Note: I have assumed your @page start at 1 and also changed the where clause 
      to bring correct data based on @page & @unitItems parameters 
    */
    SELECT IT.*, CEILING(CAST(RN AS float) / 20) AS UNITPAGES, RN AS UNITROWS
    FROM vSequence IT INNER JOIN (SELECT Max(RowNumber) AS RN FROM vSequence) SUBQ ON 1=1
    WHERE IT.RowNumber BETWEEN (@unitItems * (@page - 1) + 1) AND @unitItems 

    /* Query 2 */
    SELECT  IT.CATID,RS.CATNAME , CONVERT(varchar(10), 
            SUM(CASE WHEN IT.CATID = CAT.CATID THEN    1 ELSE 0 END)) AS 'Count'
    FROM vSequence RS 
              INNER JOIN ITEM IT ON RS.CATID = IT.CATID 
              INNER JOIN CATEGORY CAT ON IT.CATID = CAT.CATID 
    GROUP BY IT.CATID,RS.CATNAME

    /* Query 3 */
    SELECT  CIT.CITYID,CITYNAME,CONVERT(varchar(10), 
            SUM(CASE WHEN CIT.REGIONID =   REG.REGIONID THEN 1 ELSE 0 END)) AS 'Count'
    FROM COUNTRY CON 
             INNER JOIN REGION REG ON CON.COUNTRYISO = REG.COUNTRYISO
             INNER JOIN CITY CIT ON CIT.REGIONID =  REG.REGIONID
             INNER JOIN  vSequence RS ON CIT.CITYID=RS.CITYID 
    GROUP BY REG.REGIONID,CITYNAME, CIT.CITYID
 END
以下是如何在
Management Studio
中执行存储过程(请为参数使用适当的值):

要在
C
代码中执行此存储过程,请使用带有
DataAdapter
的参数化查询,如下所示:

DataSet ds = new DataSet();
using (SqlConnection connection =  new SqlConnection("your-Connection-String-here"))
{

    SqlDataAdapter adapter = new SqlDataAdapter();
    adapter.SelectCommand = new SqlCommand("myStoredProcedure", connection);
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
    adapter.SelectCommand.Parameters.AddWithValue("@unitItems",20);
    //add other parameters as above here
    adapter.SelectCommand.Parameters.AddWithValue("@page",1); //correct page number
    adapter.Fill(ds);
}

//Now you can access all query results as 
ds.Tables[0]; //results from query1
ds.Tables[1]; //results from query2
ds.Tables[2]; //results from query3

最后,我创建了下面的SP并解决了问题

请告诉我这是正确的方法吗?

我使用了临时表、分组集、分组ID

你可以在这里看到代码

创建过程[dbo]。[Item\u SearchItems\u New]
(
@购物中心
,@unitItems INT=20
,@sortOrder INT=0
,@language CHAR(2)=“EN”
,@catId INT
,@search-NVARCHAR(100)=”
,@countryIso NCHAR(2)=”
,@regionNr INT=0
,@cityId INT=0
,@maxPrice十进制(10,2)
,@page INT
,@currentDate日期时间2(0)
,@距离数字(4,1)
,@isFavoriteShop位=0
,@currentUserNr INT=0
,@纬度浮动(53)=0
,@经度浮动(53)=0
,@itemType TINYINT=0
,@unitRows INT输出
,@unitPages INT输出
)
作为
开始
将XACT_中止设置为ON
不计较
声明@sql NVARCHAR(最大值)
,@sqlSelect-NVARCHAR(最大值)=”
,@sqltentable NVARCHAR(MAX)='#itemSearch'
,@sqlcounttentable NVARCHAR(MAX)='#itemCount'
,@sqlInto NVARCHAR(最大值)=”
,@sqlFrom NVARCHAR(MAX)=”
,@sqlClause NVARCHAR(MAX)=”
,@sqlGroup NVARCHAR(最大值)=”
,@params NVARCHAR(最大值)
,@citySearch位=0
,@gpsSearch位=0
,@sortOrderString NVARCHAR(MAX)='ORDER BY IT.CREATEDATE DESC'
,@sortOrderString2 NVARCHAR(最大值)=”
如果(@cityid 0)和(@latitude=0)
选择@cityid=cityid
来自用户信息
其中USERNR=@currentUserNr
ELSE IF(@cityid 0)
设置@gpsSearch=1
ELSE IF(@cityid>0)
设置@citySearch=1
IF(@sortOrderString2='')
设置@sortOrderString2=@sortOrderString
如果(@unitItems=0)
设置@unitItems=20
如果(@page 0)
SET@sqlClause=@sqlClause+
'和(C.CATID=@CATID或C.PARENTCATID=@CATID)'
如果(@ShopNr>0)
SET@sqlClause=@sqlClause+
'IT.ShopNR=@ShopNR'
如果(@搜索“”)
SET@sqlClause=@sqlClause+
'和((类似于'%'+@search+'%''的IT.HEADER)或(类似于'%'+@search+'%''的IT.DESCRIPTION))'
将@sqlInto='设置为'+@sqltentable+'';
SET@sql=@sqlSelect+
@sqlInto+
@sqlFrom+
@SQL子句+
@sqlGroup
设置@sql=@sql+';
选择@unitRows=@@ROWCOUNT
,@unitPages=(@unitRows/@unitItems)+1;
挑选*
从“++@sqltentable+”开始
其中(@page-1)*@unitItems+1和@unitItems*@page之间的行号
“+@sortOrderString2+”;
选择CATNAME
城市
,计数(*)为ITEMCOUNT
,将_ID(CATNAME,CITY)分组为ITEMCOUNTTYPEID
进入“++@sqlcountetreable+”
来自“++@sqltentable+”
按分组集分组
(
DataSet ds = new DataSet();
using (SqlConnection connection =  new SqlConnection("your-Connection-String-here"))
{

    SqlDataAdapter adapter = new SqlDataAdapter();
    adapter.SelectCommand = new SqlCommand("myStoredProcedure", connection);
    adapter.SelectCommand.CommandType = CommandType.StoredProcedure;
    adapter.SelectCommand.Parameters.AddWithValue("@unitItems",20);
    //add other parameters as above here
    adapter.SelectCommand.Parameters.AddWithValue("@page",1); //correct page number
    adapter.Fill(ds);
}

//Now you can access all query results as 
ds.Tables[0]; //results from query1
ds.Tables[1]; //results from query2
ds.Tables[2]; //results from query3
 CREATE PROCEDURE [dbo].[Item_SearchItems_New]
 (
   @ShopNr INT
,@unitItems INT = 20
,@sortOrder INT = 0
,@language CHAR(2) = 'EN'
,@catId INT
,@search NVARCHAR(100) = ''
,@countryIso NCHAR(2) = ''
,@regionNr INT = 0
,@cityId INT = 0
,@maxPrice DECIMAL(10, 2)
,@page INT
,@currentDate DATETIME2(0)
,@distance NUMERIC(4, 1)
,@isFavoriteShop BIT = 0
,@currentUserNr INT = 0
,@latitude FLOAT(53) = 0
,@longitude FLOAT(53) = 0
,@itemType TINYINT = 0
,@unitRows INT OUTPUT
,@unitPages INT OUTPUT
 )
 AS
 BEGIN
SET XACT_ABORT ON
SET NOCOUNT ON

DECLARE @sql NVARCHAR(MAX)
        ,@sqlSelect NVARCHAR(MAX) = ''
        ,@sqlTempTable NVARCHAR(MAX) = '#itemSearch'
        ,@sqlCountTempTable NVARCHAR(MAX) = '#itemCount'
        ,@sqlInto NVARCHAR(MAX) = ''
        ,@sqlFrom NVARCHAR(MAX) = ''
        ,@sqlClause NVARCHAR(MAX) = ''
        ,@sqlGroup NVARCHAR(MAX) = ''
        ,@params NVARCHAR(MAX)
        ,@citySearch bit = 0
        ,@gpsSearch bit = 0
        ,@sortOrderString NVARCHAR(MAX) = 'ORDER BY IT.CREATEDATE DESC'
        ,@sortOrderString2 NVARCHAR(MAX) = ''

IF (@cityid <= 0) AND (@currentUserNr > 0) AND (@latitude = 0)
    SELECT  @cityid = CITYID
    FROM    USERINFO
    WHERE   USERNR = @currentUserNr
ELSE IF (@cityid <= 0) AND (@latitude > 0)
    SET @gpsSearch = 1
ELSE IF (@cityid > 0)
    SET @citySearch = 1



IF (@sortOrderString2 = '')
    SET @sortOrderString2 = @sortOrderString

IF (@unitItems = 0)
    SET @unitItems = 20

IF (@page <= 0)
    SET @page = 1

SET @sqlSelect =
    'SELECT     J.URLNAME
                ,IT.ITEMNR
                ,IT.USERNR
                ,IT.ShopNR
                ,IT.ITEMID
                ,IT.ITEMNAME
                ,IT.HEADER
                ,IT.DESCRIPTION
                ,IT.PRICE
                ,IT.CREATEDATE
                ,IT.ITEMSTATUS
                ,IT.CURRENCYCODE
                ,IT.CATID
                ,IT.VISIT
                ,IT.ENDDATE
                ,IT.PREAMBLE
                ,IT.SHOWDATE
                ,IT.LASTUPDATED
                ,C.CATNAME AS CATNAME

                ,J.HEADER AS ShopHEADER
                ,J.LATITUDE
                ,J.LONGITUDE
                ,R.REGIONNAME AS REGIONNAME
                ,CY.COUNTRYISO
                ,R.REGIONNR
                ,CY.COUNTRYNAME AS COUNTRYNAME
                ,CI.CITYNAME AS CITY
                ,ROW_NUMBER() OVER (' + @sortOrderString + ') AS RowNumber'

SET @sqlGroup =
    ' GROUP BY  J.URLNAME
                ,IT.ITEMNR
                ,IT.USERNR
                ,IT.ShopNR
                ,IT.ITEMID
                ,IT.ITEMNAME
                ,IT.HEADER
                ,IT.DESCRIPTION
                ,IT.PRICE
                ,IT.CREATEDATE
                ,IT.ITEMSTATUS
                ,IT.CURRENCYCODE
                ,IT.CATID
                ,IT.VISIT
                ,IT.ENDDATE
                ,IT.PREAMBLE
                ,IT.SHOWDATE
                ,IT.LASTUPDATED
                ,C.CATNAME

                ,J.HEADER
                ,J.LATITUDE
                ,J.LONGITUDE
                ,R.REGIONNAME
                ,CY.COUNTRYISO
                ,R.REGIONNR
                ,CY.COUNTRYNAME
                ,CI.CITYNAME'

SET @sqlFrom =
    ' FROM      dbo.ITEM AS IT
    INNER JOIN  dbo.Shop AS J
            ON  IT.ShopNR = J.ShopNR
    INNER JOIN  dbo.CITY AS CI
            ON  CI.CITYID = J.CITYID
    INNER JOIN  dbo.COUNTRY AS CY
            ON  CI.COUNTRYISO = CY.COUNTRYISO
    INNER JOIN  dbo.REGION AS R
            ON  CI.REGIONNR = R.REGIONNR'

    SET @sqlFrom = @sqlFrom +
        ' INNER JOIN    dbo.CATEGORY AS C
                ON  IT.CATID = C.CATID '

    SET @sqlClause =
        ' WHERE     J.ACTIVE = 1
                AND IT.ITEMSTATUS = 1
                AND IT.ENDDATE > @currentDate'      

    IF (@itemType = 1) 
        SET @sqlClause = @sqlClause +
            ' AND IT.ITEMTYPE = 1'

    IF (@catId > 0)
        SET @sqlClause = @sqlClause +
            ' AND (C.CATID = @catId OR C.PARENTCATID = @catId)'

    IF (@ShopNr > 0)
        SET @sqlClause = @sqlClause +
            ' AND IT.ShopNR = @ShopNr'

    IF (@search <> '') 
        SET @sqlClause = @sqlClause +
            ' AND ((IT.HEADER LIKE ''%' + @search + '%'') OR (IT.DESCRIPTION LIKE ''%' + @search + '%''))'

    SET @sqlInto = ' INTO ' + @sqlTempTable + ' ';

    SET @sql =  @sqlSelect +
                @sqlInto +
                @sqlFrom +
                @sqlClause +
                @sqlGroup

    SET @sql = @sql + ';

        SELECT  @unitRows = @@ROWCOUNT
                ,@unitPages = (@unitRows / @unitItems) + 1;

        SELECT  *
        FROM    ' + @sqlTempTable + ' AS IT
        WHERE   RowNumber BETWEEN (@page - 1) * @unitItems + 1 AND @unitItems * @page
        ' + @sortOrderString2 + ';

        SELECT      CATNAME
                    ,CITY
                    ,COUNT(*) AS ITEMCOUNT
                    ,GROUPING_ID(CATNAME, CITY) AS ITEMCOUNTTYPEID
        INTO        '+ @sqlCountTempTable + '
        FROM        ' + @sqlTempTable + '
        GROUP BY    GROUPING SETS
                    (
                        (CATNAME)
                        ,(CITY)
                        ,()
                    )

        SELECT      ISNULL(CATNAME, ''All Categories'') AS CATNAME
                    ,ITEMCOUNT
        FROM        '+ @sqlCountTempTable + '
        WHERE       ITEMCOUNTTYPEID IN (1, 3)
        ORDER BY    ITEMCOUNTTYPEID DESC
                    ,CATNAME

        SELECT      ISNULL(CITY, ''All Cities'') AS CITY
                    ,ITEMCOUNT
        FROM        '+ @sqlCountTempTable + '
        WHERE       ITEMCOUNTTYPEID IN (2, 3)
        ORDER BY    ITEMCOUNTTYPEID DESC
                    ,CITY';

    SELECT @params =
        N'@language nchar(2), ' +
        N'@ShopNr int, ' +
        N'@cityId int, ' +
        N'@catId int, ' +
        N'@distance numeric(4,1), ' +
        N'@currentDate datetime, ' + 
        N'@unitItems int,' + 
        N'@countryIso nchar(2),' + 
        N'@regionNr int,' + 
        N'@page int,' + 
        N'@currentUserNr int,' +
        N'@latitude float,' +
        N'@longitude float,' +
        N'@unitRows int OUTPUT,' +
        N'@unitPages int OUTPUT'

--print @sql

EXEC    sp_executesql @sql
        ,@params
        ,@language
        ,@ShopNr
        ,@cityId
        ,@catId
        ,@distance
        ,@currentDate
        ,@unitItems
        ,@countryIso
        ,@regionNr
        ,@page
        ,@currentUserNr
        ,@latitude
        ,@longitude
        ,@unitRows OUTPUT
        ,@unitPages OUTPUT
END
GO


DECLARE @unitPages INT
    ,@unitRows INT

exec Item_SearchItems_New @ShopNr=0,@unitItems=20,@catId=0,@language='',@sortOrder=0,@search=default,@countryIso='in',
@regionNr=2702259,@cityId=2702261,@maxPrice=0,@page=1,@distance=50,@currentDate='2013-02-24 19:29:50.623',@isFavoriteShop=0,
@currentUserNr=0,@latitude=0,@longitude=0,@itemType=0,@unitRows = @unitRows OUTPUT, @unitPages = @unitPages OUTPUT

SELECT  @unitPages, @unitRows