0

私は2つのテーブルを持っています:

  • ビジネス(id、name)
  • カテゴリ(id、name、business_id)

各カテゴリに5つのビジネスがあるデータベースのすべてのカテゴリを出力するにはどうすればよいですか?

たとえば、データベースに3つのカテゴリがある場合、次のようにします。

category 1
--------------
business 1
business 2
business 3
business 4
business 5

category 2
---------------
business 6
business 7
business 8
business 9
business 10

category 3
------------------
business 11
business 12
business 13
business 14
business 15

私がそれを行う方法を知っている唯一の方法は、dbからすべてのカテゴリをフェッチしてから、プログラムで各カテゴリをループし、別のクエリを実行して各カテゴリのすべてのビジネスを取得することです。

それを行う他の方法はありますか?

4

3 に答える 3

2

ランク メソッドを使用できますが、これにはサブクエリが含まれます。

 select id,business_name,cat_name,cat_id from
(SELECT *,@i := CASE WHEN ( @temp_bid <> m.id ) THEN 1                      
            ELSE     @i+1      
            END AS rank ,
            @temp_bid:=m.id as dlset 
 FROM 
 ( Select a.id as id,a.name as business_name,b.name as cat_name,b.id as cat_id
   from business a left outer join categories b on a.id=b.business_id ) m)k,
 (SELECT @i:=0)i,(SELECT @i2:=0)i2
where rank<=5
 ORDER BY business_name,rank desc;

SQL FIDDLE HERE.

于 2012-08-09T01:57:39.320 に答える
1

これは、WHERE句の相関サブクエリを使用して実行できます。

select b.name, c.id
from categories c join
     business b
     on c.business_id = b.id
where c.id in (select c2.id
               from categories c2
               where c2.business_id = c.business_id
               order by rand()
               limit 5
              )

ランキング機能をサポートする他のデータベースでは、これははるかに簡単です。

このサブクエリで制限がサポートされていない場合は、自己結合を使用して制限を行う必要があります。うん、うん、うん:

with bc as (
     select b.name, c.id
     from categories c join
          business b
          on c.business_id = b.id
   )
select bc.name, bc.id
from bc join
     bc bcprev
     on bc.name = bcprev.name and
        bcprev.id <= bc.id
group by bc.name, bc.id
having count(*) <= 5

これは5つのランダムなカテゴリを取得しません。代わりに、IDが最小の5つを取得します。

ロススミスによる編集:

上記のクエリはMySQL5.5.25でエラーを返しますが、以下は機能します。

select bc.name, bc.id
from
  (
     select b.name, c.id
     from categories c join
          business b
          on c.business_id = b.id
   ) bc join
   (
     select b.name, c.id
     from categories c join
          business b
          on c.business_id = b.id
   ) bcprev
     on bc.name = bcprev.name and
        bcprev.id <= bc.id
group by bc.name, bc.id
having count(*) <= 5

そして、この期待される結果を返すようです。

http://sqlfiddle.com/#!2/ea78a/9を参照してください

于 2012-08-09T02:13:54.133 に答える
0

カテゴリとビジネスの関係を別のテーブルに格納した方がよいのではないでしょうか。その場合は、次のクエリを使用できます。

SELECT
    c_name,
    b_name
FROM
(
    SELECT
        c.name AS c_name,
        b.name AS b_name,
        (@row := IF(@last = cat_id, @row + 1, 1)) AS row,
        @last := cat_id
    FROM
        (SELECT @row := 0, @last = '') a,
        cat_bus cb
    INNER JOIN
        cat c ON c.id = cb.cat_id
    INNER JOIN
        bus b ON b.id = cb.bus_id
    ORDER BY
        c.name,
        b.name
) d 
WHERE
    d.row <= 5
ORDER BY
    c_name,
    b_name  

結果については、 sqlfiddle.comを参照してください。

于 2012-08-09T03:25:18.007 に答える