2

データベースのテーブルに4つのカテゴリがあります。
データベースのすべてのカテゴリから最も訪問された4つの記事を取得したいと思います。
これは、から(4 articles most visited from category1)+ (4 articles most visited from category2)++ (4 articles most visited from category3)=(4 articles most visited from category4)合計を取得することを意味します。 16 articles4 categories

1つのクエリでそれを実行したいと思います。

通常のクエリ:

$sql="select ID,name,country from article where `active`='yes' order by `visit` desc limit 16 ";

記事のテーブル構造:

CREATE TABLE `article` (
  `ID` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `country` varchar(50) NOT NULL default '',
  `town` varchar(30) NOT NULL default '',
  `other_town` varchar(30) NOT NULL default '',
  `title` varchar(255) NOT NULL default '0',
  `size` varchar(30) NOT NULL default '',
  `type` varchar(30) NOT NULL default '',
  `tel` varchar(30) NOT NULL default '',
  `mobile` varchar(30) NOT NULL default '',
  `connect` varchar(30) NOT NULL default '',
  `email` varchar(30) NOT NULL default '',
  `photo1` varchar(100) NOT NULL default '',
  `print` varchar(30) NOT NULL default '',
  `small_pic1` varchar(100) NOT NULL default '',
  `detail` text NOT NULL,
  `add_by` int(11) NOT NULL default '0',
  `cat` int(11) NOT NULL default '0',
  `goods_type` enum('new','old') NOT NULL,
  `add_date` date NOT NULL default '0000-00-00',
  `end_date` date NOT NULL default '0000-00-00',
  `period` varchar(30) NOT NULL default '',
  `visit` int(11) NOT NULL default '0',
  `comment` int(30) NOT NULL default '0',
  `fav` varchar(15) NOT NULL default '',
  `favorite` varchar(15) NOT NULL default '',
  `active` varchar(15) NOT NULL default '',
  `rate` int(11) NOT NULL default '0',
  `short` text NOT NULL,
  `add_to` varchar(50) NOT NULL default '',
  `author` varchar(50) NOT NULL default '',
  `author_img` varchar(50) NOT NULL default '',
  `lang` varchar(10) NOT NULL default '',
  `budget` varchar(50) NOT NULL default '',
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 ;

カテゴリテーブルの構造:

CREATE TABLE `category` (
  `ID` int(11) NOT NULL auto_increment,
  `name` varchar(255) NOT NULL default '',
  `img` varchar(255) NOT NULL default '',
  `sub` int(11) NOT NULL default '0',
  `type` varchar(20) NOT NULL default '',
  `lang` varchar(10) NOT NULL default '',
  `active` varchar(25) NOT NULL default '',
  `add_by` int(11) NOT NULL default '0',
  PRIMARY KEY  (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1;
4

3 に答える 3

1

これは可能ですが、100%簡単ではありません。以前に読んだSOの質問からこの記事をブックマークしました(これも検索/リンクします)。基本的に、クエリごとにこの1つのグループが必要な場合は、ORDER BYとLIMITを使用できますが、すべてを1つのクエリで実行するには、これについて詳しく説明しているリンク先の記事に従ってください。

http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/

後世のために、彼が提供する最初の方法に基づいた要約クエリの例を投稿します。これは、カテゴリの数に比例して時間とともに指数関数的に増加する可能性があります。

select ID, name, country, cat, visit
from article
where visit = (select max(visit) from article as a where a.cat = article.cat)
or visit = (select max(visit) from article as a where a.cat = article.cat
   and visit < (select max(visit) from article as a2 where a2.cat = article.cat))

or visit = (select max(visit) from article as a where a.cat = article.cat
  and a.visit < (select max(a2.visit) from article as a2 where a2.cat = article.cat
  and a2.visit < (select max(a3.visit) from article as a3 where a3.cat = article.cat)))

or visit = (select max(visit) from article as a where a.cat = article.cat
  and a.visit < (select max(a2.visit) from article as a2 where a2.cat = article.cat
  and a2.visit < (select max(a3.visit) from article as a3 where a3.cat = article.cat
  and a3.visit < (select max(a4.visit) from article as a4 where a4.cat =    article.cat))))
order by cat, visit desc

または、カテゴリを指定せずに注文する場合は、descにアクセスして注文してください。

これにより、各カテゴリの上位4つが返されますが、探しているレベルごとのクエリのネストに注意してください。さらに深く進む必要がある場合は、彼の指示に従って、より深いオプションを選択してください(彼、および私はこれをYUCKと説明します) 。

SQLフィドル:http ://www.sqlfiddle.com/#!2 / e115f / 26

後世のためにも、私のテストデータ:

CREATE TABLE article (
 ID int auto_increment primary key, 
 name varchar(20), 
 country varchar(30),
 cat int,
 visit int
);

INSERT INTO article (name, country, cat, visit) VALUES
 ('Test1', 'Canada', 1, 7),('Test2', 'Canada', 1, 2),('Test3', 'Ireland', 1, 1),
 ('Test5', 'Ireland', 1, 3),('Test6', 'Ireland', 1, 8),('Test7', 'India', 1, 9),
 ('Test8', 'Canada', 2, 11),('Test9', 'Canada', 2, 13),('Test10', 'Ireland', 2, 6),
 ('Test11', 'Ireland', 2, 5),('Test12', 'Ireland', 2, 1),('Test13', 'India', 3, 1),
 ('Test14', 'India', 3, 9),('Test15', 'India', 3, 8),('Test16', 'India', 3, 54);
于 2013-02-13T15:59:51.860 に答える
1

これでうまくいくはずです。基本的に、カテゴリごとに行番号を決定し、次に訪問列で並べ替えて、上位4つを選択します。これは要約バージョンですが、ポイントを取得する必要があります(返される必要のあるフィールドを追加します)。

SELECT Id, Cat, Visit, Name
FROM (
    SELECT 
      @curRow:=CASE WHEN @prevRow = A.cat THEN @curRow+1 ELSE 1 END AS rn,
      A.Id, 
      A.Visit,
      A.Cat, A.Name, 
      @prevRow:=A.cat AS clset
    FROM (SELECT A.Id, C.Id as Cat, A.Visit, C.Name
          FROM Articles A
            JOIN Category C ON A.cat = C.id
          ORDER BY A.Cat, A.Visit DESC
          ) A
      JOIN (SELECT @curRow:=0) r
      JOIN (SELECT @prevRow:=0) r2
  ) B
  WHERE rn <= 4

そしていくつかのフィドル:http ://sqlfiddle.com/#!2 / b7260 / 1

幸運を。

于 2013-02-13T16:02:58.363 に答える
0

これを試して:

SELECT ID, NAME, country, catCnt 
FROM (SELECT ID, NAME, country, cat, IF(@cat=(@cat:=cat), @cnt:=@cnt+1, @cnt:=1) catCnt 
      FROM (SELECT ID, NAME, country, cat FROM article WHERE `active`='yes' ORDER BY cat, `visit` DESC) A, 
           (SELECT @cat := 0, @cnt:=1) B
      ) A 
GROUP BY cat HAVING catCnt <= 4;

また

SELECT ID, NAME, country
FROM (SELECT ID, NAME, country, cat, IF(@cat=(@cat:=cat), @cnt:=@cnt+1, @cnt:=1) catCnt 
      FROM (SELECT ID, NAME, country, cat FROM article WHERE `active`='yes' ORDER BY cat, `visit` DESC) A, 
           (SELECT @cat := 0, @cnt:=1) B
      ) A 
WHERE catCnt <= 4;
于 2013-02-13T16:03:15.077 に答える