0

と の 2 つのテーブルがitemsありitems_purchasedます。名前とその他のtag説明情報がitemsテーブルにあり、各アイテムの購入数がテーブルに保存されitems_purchasedます。テーブルはJOINitem_id で編集されます。

これまでの私のクエリは次のとおりです。

(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'History' and deleted!=1 and pub_priv!=1    order by tots desc limit 1)
UNION ALL
(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'Medicine' and deleted!=1 and pub_priv!=1  order by tots desc limit 1)
UNION ALL
(select *, sum(purchaseyesno) as tots from items join items_purchased on items.item_id=items_purchased.item_id where tag = 'Biology' and deleted!=1 and pub_priv!=1  order by tots desc limit 1)
//... more tags (20 in all) would follow

問題は、特定のタグが付いたアイテムがまだ購入されていないため、クエリでエラーがスローされることですColumn "item_id" cannot be null

サンプルテーブルは次のとおりです。

            items              |     items_purchased   |   
  item_id   tag      title     | item_id  purchaseyesno|
    1     Biology  DNA is cool |    1         1        | 
    2     Medicine  Doctors    |    2         1        |  
    3      Law    Laws are cool|    4         1        |    
    4     Biology DNA NOT cool |    1         1        |

サンプル結果:

item_id   tag       title      tots
  1      Biology   DNA is cool  2
  2      Medicine  Doctors      1
  3       Law   Laws are cool   0

2 つの質問:

  1. SELECT結果が次のようになる場合、これらのステートメントのいずれかを除外するにはどうすればよいNULLですか?
  2. UNION ALL19 sで結合された 20 の select ステートメントではなく、このクエリを実行するためのより良い方法はありますか?
4

2 に答える 2

2

結果をグループ化するだけです。それ以上に複雑なことはありません (UNION見えない!)。

SELECT   items.*, SUM(purchaseyesno) AS tots
FROM     items JOIN items_purchased USING (item_id)
GROUP BY item_id

アップデート

以下のコメントと OP の質問の更新に続いて、問題が最初に考えられていたよりも複雑であることは明らかです。実際、これはグループごとの最大問題の特殊なケースです。

ただし、最大値を取得する必要がある列は、それ自体が別のグループごとの集計 (の合計purchaseyesno) の結果です。

したがって、サブクエリを使用すると、クエリはかなり洗練されなくなります。

SELECT *
FROM (
  SELECT   items.*, IFNULL(SUM(purchaseyesno),0) AS tots
  FROM     items LEFT JOIN items_purchased ON folder_id = item_id
  GROUP BY item_id
) AS t NATURAL JOIN (
  SELECT tag, MAX(tots) AS tots
  FROM (
    SELECT   items.*, IFNULL(SUM(purchaseyesno),0) AS tots
    FROM     items LEFT JOIN items_purchased ON folder_id = item_id
    GROUP BY item_id
  ) AS u
  GROUP BY tag
) AS v
GROUP BY tag

sqlfiddleで参照してください。

ここで何が起こっているかというと、(外部結合Lawを使用してテーブルに参照がないレコードなどを含めるitems_purchased)、各アイテム (実体化されたテーブルu) の購入の合計を取得し、同じアイテムの最大購入数を決定します。タグ名。

次に、タグ名と購入数の両方で、結果 (具体化された table ) をv最初のテーブル ( u、再び table として具体化)に結合します。t

最後にtag、同じタグを持つ複数のアイテムの最大購入数が同じ場合、そのうちの 1 つだけが不確定に返されるように、結果を再度グループ化します。

于 2012-06-26T10:54:00.060 に答える
0

マスター テーブル tags を作成し、その ID を名前として使用されるテーブルに格納します。次に、以下のクエリが問題の解決策になります..

select *, sum(purchaseyesno) as tots 
from items left join 
items_purchased ip on (items.item_id=items_purchased.item_id)
inner join tag_table on (tag_table.id=tagId)
where  deleted!=1 and pub_priv!=1 and not items.item_id is null group by tagID
于 2012-06-26T10:44:41.073 に答える