8

asp.net mvc アプリケーションと c# を使用します。検索ページを作成中です。

私の回答で更新されました。以下の私自身の答えを見て、提案してください

残念ながら、select into は sql azure http://blogs.msdn.com/b/sqlazure/archive/2010/05/04/10007212.aspxで機能しません。

助けて

アイテムの検索結果を表示するために、以下のテーブルがあります

アイテムテーブル

  • ITEMID,SHOPID, ITEMNAME, DESCRIPTION, PRICE,CATID

ショップテーブル

  • SHOPID、HEADER、CITYID、ACTIVE

シティテーブル

  • 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 で表示される検索結果

2 番目の結果セット --> 異なるカテゴリと 230 レコードからのカウント

CatId、CatName、TotalCountInSearch

例: 1 本 25 & 2 スポーツ 43 & 8 その他 52. 表示 UI で次のように表示できます

  • すべてのカテゴリ (120)
  • 本 (25)
  • スポーツ (43)
  • その他 (52)

そして3 番目の結果セット --> 異なる都市 & 230 レコードからカウント

CityId、CityName、TotalCountInSearch

UIの下に表示するため

  • すべての都市(10)
  • チェンナイ (4)
  • バンガロール (3)
  • その他 (3)

すべてのカテゴリ、本、すべての都市などの数と名前を取得するにはどうすればよいですか? ヘルプや提案は大歓迎です。

ここをクリックして SQL Fiddle を表示

検索条件に基づいてこれらの数を取得したいと思います。私の手順か​​ら別の結果セットとしてこれを取得したい

主な更新:

すべてのスキーマと実際の動的クエリをここにアップロードしました https://github.com/Padayappa/SQLProblem/blob/master/PaginationIssue

4

4 に答える 4

4

これを試して。これがあなたの期待を満足させることを願っています

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

SQL フィドルのサンプル。

于 2013-03-04T13:37:47.600 に答える
3

あなたのコメントから私が理解しているように、私はあなたが得る必要3 result sets by executing a single stored procedureがあると思います. また、クエリが最適化されているかどうかも知りたいです。

あなたのvSequence VIEWはそのままで問題ないと思います(したがって、ここで回答に追加していません)。必要なのは、以下create a stored procedureの 3 つの異なる結果セットを取得することusing your viewです。フィドルで宣言した変数リストを、ストアド プロシージャのパラメーターとして取得しました。各変数の横にコメントしました。フィルタリング要件が明確でないため、そのままにしておきます。

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(パラメーターには適切な値を使用してください)。

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

EXEC myStoredProcedure 
       @unitItems,
       @sortOrder,
       @catId,
       @search,
       @REGIONID,
       @cityId,
       @maxPrice,
       @page,
       @currentDate

コード内でこのストアド プロシージャを実行するには、次のよう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
于 2013-03-04T16:40:10.697 に答える
1

最後に、以下のSPを作成して問題を解決しました。

これが正しいアプローチかどうか教えてください。

一時テーブル、Grouping SETS、Grouping_ID を使用しました

ここでコードを見ることができますhttps://github.com/Padayappa/SQLProblem/blob/master/PaginationResolved

 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
于 2013-03-10T12:26:35.717 に答える
0

これは、カテゴリに基づいてカウントを取得することです

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
于 2013-03-02T07:54:43.517 に答える