1

私はいくつかのSQLと戦ってきましたが、頭を悩ませているようには見えません。

1 つはカテゴリのリスト、もう 1 つはすべての記事を含む 2 つのテーブルがあります。

私がやろうとしているのは、各カテゴリにいくつの記事が存在するかを見つけることです。

ここに私がこれまでに持っているSQLがあります

SELECT DISTINCT COUNT( po.post_Cat_ID ) AS Occurances, ca.cat_Title
FROM Posts po, Categories ca
WHERE ca.cat_ID = LEFT( po.post_Cat_ID, 2 )

LEFT を使用する理由は、次のようにカテゴリをリストしたため、主要なカテゴリのみを取得するためです...たとえば

Science = 01
Medicine = 0101
Sport = 02

したがって、asprin の投稿の cat_ID は 0101 になります (LEFT は 0101、0102、0103 などを 01 にトリムします)。基本的にサブカテゴリには興味がありません。

前もって感謝します


結果

SELECT DISTINCT COUNT( po.post_Cat_ID ) AS Occurances, ca.cat_Title
FROM Posts po, Categories ca
WHERE ca.cat_ID = LEFT( po.post_Cat_ID, 2 )
GROUP BY LEFT( po.post_Cat_ID, 2 )

psありがとう@nullpointer、それは今のところ機能します。他の読者のために再構築を検討します

http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

4

2 に答える 2

0

代わりに、スキーマを再構築することをお勧めします。ここで必要なのは、階層構造 (カテゴリ) を表すことですが、これはリレーショナル データベースで行うのは簡単ではありません。2 つの一般的なソリューションは、隣接リストとネストされたセットです。

隣接リストは、より単純なツリーのような構造です。categories次のようなテーブルがあります。

id  | name      | parent
------------------------
1   | Science   | null
2   | Sports    | null
3   | Medicine  | 1

残念ながら、このモデルは SQL を使用して操作するのは困難です。代わりに、ネストされた集合アプローチを使用できます。ここで、すべてのノードには、親の値と値の間にある値ノードがlftあります。あなたの例では、次のようになります。rgtlftrgt

id  | name      | lft  | rgt  
-------------------------------
1   | Science   | 1    | 4    
2   | Sports    | 5    | 6 
3   | Medicine  | 2    | 3

したがって、特定のカテゴリのカウントを取得するには、必要なカテゴリの間にlftrgtの値を持つノードの数をクエリするだけです。例えば:

   SELECT COUNT(*) 
     FROM articles a
LEFT JOIN categories c ON a.category_id = c.id
    WHERE lft BETWEEN 1 AND 4 
      AND rgt BETWEEN 1 AND 4

articleテーブルが次のようになっていると仮定します。

id  | ... | category_id

これについては、http: //mikehillyer.com/articles/managing-hierarchical-data-in-mysql/で詳しく説明しています。


別の解決策を提案します。カテゴリではなくタグを使用します。特定の記事に複数のタグを使用して、特定のタグに一致するすべての記事の数を簡単に取得できます。これにより、作業がはるかに簡単になり、柔軟性も大幅に向上します。

これを実現するには、記事とタグの間に多対多の関係が必要です。これは通常、ジャンクション テーブルで実装されます。

tags
id  | name

articles_tags # the junction table
article_id  | tag_id

記事にタグを付けるには、正しいとを使用してテーブルにINSERT複数のエントリを入力するだけです。次に、通常どおり s を使用して、必要なものを取得できます。articles_tagsarticle_idtag_idJOIN

于 2010-09-04T13:49:32.773 に答える
0

列をカテゴリに追加して、各カテゴリが含まれるメイン カテゴリを指定します (メイン カテゴリ自体を指定します)。そう:

cat_id | main_cat_id | title
-------+-------------+---------
01     | 01          | Science
0101   | 01          | Medicine
02     | 02          | Sport

ここから cat_id = main_cat_id を選択してメイン カテゴリを検索します。left.cat_id = right.main_cat_id で自分自身に結合して子カテゴリを見つけ、次に cat_id = cat_id の投稿に結合します。left.cat_id でグループ化し、cat_id と count(*) でプロジェクトします。

PostgreSQL 8.4 でこれを試しましたが、クエリが非常に基本的であるため、なぜこれが MySQL で機能しないのかわかりません。私のテーブル:

create table categories(
  cat_id varchar(40) primary key,
  main_cat_id varchar(40) not null references categories,
  title varchar(40) not null
)

create table posts (
  post_id integer primary key,
  cat_id varchar(40) not null references categories,
  title varchar(40) not null
)

私のクエリ(IDではなくタイトルによるグループ化):

select m.title, count(*)
from categories m, categories c, posts p
where m.cat_id = c.main_cat_id
  and c.cat_id = p.cat_id
group by m.title

更新:OPが試みたように、文字列操作でこれを機能させることも試みました。クエリ (MySQL の方言ではなく、PostgreSQL で受け入れられている標準準拠の SQL) は次のとおりです。

select m.title, count(*)
from categories m, posts p
where m.cat_id = substring(p.cat_id from 1 for 2)
group by m.title;

これはうまくいきます。速度に関して有意義な比較を行うことはできませんが、このクエリ プランは、双方向結合のクエリ プランよりも少し単純に見えました。

于 2010-09-04T14:11:32.543 に答える