3

こんにちはStackOverFlowメンバー

レポート=テーブル名。

データベース

CREATE TABLE `reports` (
  `id` int(11) NOT NULL auto_increment,
  `report_day_name` varchar(20) NOT NULL,
  `report_day` varchar(20) NOT NULL,
  `report_month` varchar(20) NOT NULL,
  `report_year` varchar(20) NOT NULL,
  `report_result_number` varchar(20) NOT NULL,
  `report_result_text` varchar(20) NOT NULL,
  `report_since` varchar(20) NOT NULL,
  `report_date` varchar(20) NOT NULL,
  `catid` int(11) NOT NULL,
  `subjectid` int(11) NOT NULL,
  `userid` int(11) NOT NULL,
  `groupid` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=78 ;

INSERT INTO `reports` VALUES (73, 'day', '14', '1', '1434 h', '5', 'rate', '1234567890', '1434-1-14', 1, 132, 33, 35);
INSERT INTO `reports` VALUES (74, 'day', '12', '2', '1435 h', '4', 'rate', '1234567890', '1434-2-12', 2, 136, 36, 35);
INSERT INTO `reports` VALUES (75, 'day', '14', '1', '1434 h', '2', 'rate', '1354488730', '1434-1-14', 1, 132, 33, 35);
INSERT INTO `reports` VALUES (76, 'day', '12', '2', '1435 h', '4', 'rate', '1354488730', '1434-2-12', 2, 137, 36, 35);
INSERT INTO `reports` VALUES (77, 'day', '12', '2', '1435 h', '1', 'rate', '1354488730', '1434-2-12', 2, 134, 33, 35);

これはデータベーステーブルです。

id  report_result_number    subjectid   userid
73  5                       132         33
74  4                       136         36
75  2                       132         33
76  4                       137         36
77  1                       134         33

したいSUM(reports.report_result_number) where (reports.subjectid) is DISTINCT

このコードを実行すると。

選択する
  users.user_id、users.user_name、users.user_country、SUM(reports.report_result_number)AS AllTotal、COUNT(DISTINCT reports.subjectid)AS TotalSubjects
から
  ユーザー
  INNERJOINはusers.user_id=reports.useridについてレポートします
GROUP BY
  users.user_id
  注文者
  AllTotal DESC LIMIT 4

AllTotalを返します

user_id user_name   user_country    AllTotal    TotalSubjects
36       name         country        8 (correct)        2
33        name        country        8 (not correct)    2
4

1 に答える 1

2

質問はいくつかの解釈に開かれています。

必要なのが、特定のサブジェクトIDとユーザーIDに1つの行しかない場合にのみ、SUM集計に含まれる値である result_report_number場合(同じサブジェクトIDに複数の行がある場合は、すべてのreport_result_numberを除外する必要があります)それらの行の...

次に、このようなものが機能します:

SELECT u.user_id
     , u.user_name
     , u.user_country
     , SUM(s.report_result_number) AS AllTotal
     , COUNT(DISTINCT r.subjectid) AS TotalSubjects
  FROM users u
  JOIN reports r
    ON r.userid = u.user_id
  JOIN ( SELECT d.userid
              , d.subjectid
              , d.report_result_number
           FROM reports d
          GROUP
             BY d.userid
              , d.subjectid
         HAVING COUNT(1) = 1
       ) s
    ON s.userid = r.userid
 GROUP
    BY u.user_id
 ORDER
    BY AllTotal DESC
 LIMIT 4


これは、要求された結果セットの1つの(奇妙な)解釈にすぎません。サンプルデータと期待される結果セットは、仕様を明確にするのに大いに役立ちます。


質問に追加したデータの場合、このクエリは次のように返されるはずです。

36 fee fi   8  2 
33 foo bar  1  2 

ユーザー33のサブジェクトID値が132の2つの行があるため、これらの行のreport_result_numberはSUMから除外されます。subjectidには2つの異なる値(132と134)があるため、:distinct:countof2を返します。


特定のユーザーのsubjectidに重複する値がない場合にのみ、SUMに値を返すように要求している場合...

SELECT u.user_id
     , u.user_name
     , u.user_country
     , IF(COUNT(DISTINCT r.subjectid) = COUNT(r.subjectid)
         ,SUM(r.report_result_number)
         ,NULL
       ) AS AllTotal
     , COUNT(DISTINCT r.subjectid) AS TotalSubjects
  FROM users u
  JOIN reports r
    ON r.userid = u.user_id
 GROUP
    BY u.user_id
 ORDER
    BY AllTotal DESC
 LIMIT 4

Hasan氏は次のように述べています...「[特定のユーザーIDのsubjectidの]値が重複している場合は、そのうちの1つを取得してください」

としてエイリアスされたインラインビューからHAVING句を削除するだけsです。これにより、1行のreport_result_numberの値が返されます。(値が返される「一致する」行は任意です。

SELECT u.user_id
     , u.user_name
     , u.user_country
     , SUM(r.report_result_number) AS AllTotal
     , COUNT(DISTINCT r.subjectid) AS TotalSubjects
  FROM users u
  JOIN ( SELECT d.userid
              , d.subjectid
              , d.report_result_number
           FROM reports d
          GROUP
             BY d.userid
              , d.subjectid
       ) r
    ON r.userid = u.user_id
 GROUP
    BY u.user_id
 ORDER
    BY AllTotal DESC
 LIMIT 4

結果セットを繰り返し可能にするために、常に最小値または最大値を取得するために、返す値を指定する集計関数を追加できます。

交換...

          , d.report_result_number

と...

          , MAX(d.report_result_number)  AS report_result_number

MAX()アグリゲートを使用すると、次のようになります。

36 fee fi   8  2
33 foo bar  6  2

(クエリは、subjectid = 132 userid = 33の場合は「5」の値を取得し、同じsubjectidの場合は「2」の値を省略します。)MAX集計がない場合、クエリは有効に(そして任意に)「」を返すことができます。 「6」の代わりに「3」。(「5」または「2」のいずれかを含めることができ、もう一方は省略できます。)

SQLフィドルはこちら

ここにMAXアグリゲートを含むSQLフィドル


Q:コードで(report_month ='number')を使用するにはどうすればよいですか?

A: GROUP BY句の前のFROM句の後に、インラインビューでWHERE句を追加します。これを置き換えます:

       FROM reports d
      GROUP

例えば

       FROM reports d
      WHERE d.report_month = 'number'
      GROUP

指定された述語を満たす行のみが返されます。

于 2012-12-12T22:08:04.617 に答える