2012-04-26 18 views
3

複雑なSQLクエリを作成しようとしましたが、正しい値で結果セットを取得できませんでした。複雑なMySQLクエリ

  • couponsテーブルにはオンラインクーポンがいくつかあります。
  • merchantsテーブルには小売業者情報が格納されており、couponsにはcoupons.merchant_idが割り当てられています。
  • branchesの表は、(距離を計算する、最寄りの支店など)latlng値で商人の枝を保持し、branches.merchant_idmerchantsテーブルに縛ら。テーブル番号およびbranchesテーブル。
  • placesテーブルには、ショッピングモールのようないくつかの特別な場所があり、branchesテーブルにbranches.place_idで結ばれています。

以下は私のテーブル構造です。

CREATE TABLE IF NOT EXISTS `branches` (
    `branch_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `merchant_id` int(11) unsigned NOT NULL DEFAULT '0', 
    `place_id` smallint(5) unsigned NOT NULL DEFAULT '0', 
    `branch` varchar(40) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    `address` varchar(255) COLLATE utf8_unicode_ci DEFAULT '', 
    `postcode` varchar(6) COLLATE utf8_unicode_ci DEFAULT '', 
    `phone` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `fax` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `lat` float(10,6) DEFAULT NULL, 
    `lng` float(10,6) DEFAULT NULL, 
    `status` tinyint(4) unsigned NOT NULL DEFAULT '1', 
    PRIMARY KEY (`branch_id`), 
    KEY `lat` (`lat`), 
    KEY `lng` (`lng`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

CREATE TABLE IF NOT EXISTS `coupons` (
    `coupon_id` mediumint(9) unsigned NOT NULL AUTO_INCREMENT, 
    `category_id` tinyint(4) unsigned NOT NULL DEFAULT '0', 
    `merchant_id` mediumint(9) unsigned NOT NULL DEFAULT '0', 
    `coupon` varchar(200) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    `description` longtext COLLATE utf8_unicode_ci, 
    `start_date` date DEFAULT NULL, 
    `end_date` date DEFAULT NULL, 
    `coupon_usage` int(10) unsigned NOT NULL DEFAULT '0', 
    `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `status` enum('active','passive','deleted','preview') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'active', 
    PRIMARY KEY (`coupon_id`), 
    KEY `start_date` (`start_date`), 
    KEY `end_date` (`end_date`), 
    KEY `merchant_id` (`merchant_id`), 
    KEY `category_id` (`category_id`), 
    KEY `status` (`status`), 
    KEY `created` (`created`), 
    FULLTEXT KEY `description` (`description`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

CREATE TABLE IF NOT EXISTS `coupons_branches` (
    `branch_id` int(11) unsigned NOT NULL DEFAULT '0', 
    `coupon_id` int(11) unsigned NOT NULL DEFAULT '0', 
    PRIMARY KEY (`branch_id`,`coupon_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 

CREATE TABLE IF NOT EXISTS `merchants` (
    `merchant_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `merchant` varchar(80) COLLATE utf8_unicode_ci NOT NULL DEFAULT '', 
    `website` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, 
    `created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    `status` enum('active','passive','deleted') COLLATE utf8_unicode_ci NOT NULL DEFAULT 'passive', 
    PRIMARY KEY (`merchant_id`), 
    KEY `status` (`status`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

CREATE TABLE IF NOT EXISTS `places` (
    `place_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT, 
    `city_id` smallint(5) unsigned NOT NULL DEFAULT '0', 
    `place` varchar(150) COLLATE utf8_unicode_ci DEFAULT NULL, 
    PRIMARY KEY (`place_id`), 
    KEY `place` (`place`), 
    KEY `city_id` (`city_id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

これは私のSQLです。

SELECT * FROM (SELECT coupons.coupon_id AS c_id, coupons.category_id, coupons.coupon, merchants.merchant_id, merchants.merchant, (((acos(sin((41.02287686 * pi()/180)) * sin((branches.lat * pi()/180)) + cos((41.02287686 * pi()/180)) * cos((branches.lat * pi()/ 180)) * cos(((29.04632806 - branches.lng) * pi()/180)))) * 180/pi()) * 60 * 1.1515 * 1.609344) as distance, COUNT(coupons.coupon_id) AS total_coupons 
FROM (`coupons`) 
INNER JOIN `coupons_branches` ON `coupons`.`coupon_id` = `coupons_branches`.`coupon_id` 
RIGHT OUTER JOIN `branches` ON `coupons_branches`.`branch_id` = `branches`.`branch_id` 
LEFT OUTER JOIN `merchants` ON `coupons`.`merchant_id` = `merchants`.`merchant_id` 
WHERE `coupons`.`status` = 'active' 
AND `merchants`.`status` = 'active' 
GROUP BY `merchants`.`merchant_id` 
HAVING `distance` <= 25000 
ORDER BY `merchants`.`merchant`) as T2 GROUP BY c_id ORDER BY merchant 

私はマーチャントの合計クーポンを調べようとしています。私はその商人からの最新のクーポンのみをリストしたいと思います。私はすべてのクーポンを記載したくありません。まずは小売業者をグループ化し、小売業者が持つクーポンの数を表示したいと思います。その後、別のページで、私はその商人に属するクーポンを表示します。

total_coupons欄を除くすべてがうまくいきます。合計クーポン列が正しく計算されません。以下のように書くと正しく計算されます。

SELECT * FROM (SELECT coupons.coupon_id, coupons.coupon_id AS c_id, coupons.category_id, coupons.coupon, merchants.merchant_id, merchants.merchant, coupons.coupon_usage, COUNT(coupons.coupon_id) AS total_coupons 
FROM (`coupons`) 
LEFT OUTER JOIN `merchants` ON `coupons`.`merchant_id` = `merchants`.`merchant_id` 
WHERE `coupons`.`status` = 'active' 
AND `merchants`.`status` = 'active' 
GROUP BY `merchants`.`merchant_id` 
ORDER BY `merchants`.`merchant`) as T2 GROUP BY c_id ORDER BY merchant 

ありbranchesplacesテーブルと間違って何かがあるが、私は見つけることができませんでした。

+0

なぜあなたのクエリに 'places'テーブルを追加していますか?そのテーブルのデータがクエリに使用されていませんか? –

+0

このクエリは少し複雑です。場合によっては、where places.place_id = XXX'節があり、検索結果を絞り込むことができます。しかし、あなたは正しいです、ここに 'places'テーブルを入れるのは間違いです。私は上記のクエリを編集しました。 –

+0

どのようにtotal_couponsが間違っていますか? – Jim

答えて

5

COUNT()の式をCOUNT(DISTINCT coupons.coupon_id)に変更してみてください。 DISTINCTキーワードがなければ、重複したクーポンも加盟店のクーポンの合計にカウントされます。私はあなたが現在ブランチに配布されているクーポンの合計だけを探していると推測しています。

+0

Martin、ありがとうございました。これは素晴らしい仕事でした:) –

+0

これを聞いてうれしい、あなたは大歓迎です! :) –