2

2つ以上のテーブルから発生するフィールドの複数のカウントを取得しようとしましたが、この質問からその問題を解決しました。

2つの条件でカウントを取得するためのネストされたクエリ

ソリューションは機能しましたが、次のデータ構造で試してみると、

実行されますが、結果は表示されません。しかし、前の質問で、私はこの種の解決策がうまく機能したことを投稿しました..誰かがこの問題について助けてくれますか..それは構文エラーがあるとさえ言っていません。

編集:SQLクエリ

SELECT t1.timeStamp, t1.localIp, t2.localPort, t3.localGeo, t4.isp, t5.foreignIp, t6.foreignPort, t7.foreignGeo, t8.infection,t1.timeStampCount, t1.localIpCount, t2.localPortCount, t3.localGeoCount, t4.ispCount, t5.foreignIpCount, t6.foreignPortCount, t7.foreignGeoCount, t8.infectionCount
FROM
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(timeStamp) AS 'timeStampCount',COUNT(localIp) AS 'localIpCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp)t1  
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(localPort) AS 'localPortCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort)t2  
ON t1.timeStamp=t2.timeStamp 
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(localGeo) AS 'localGeoCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort,localGeo)t3  
ON t1.timeStamp=t3.timeStamp 
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(isp) AS 'ispCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort,localGeo,isp)t4  
ON t1.timeStamp=t4.timeStamp 
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(foreignIp) AS 'foreignIpCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort,localGeo,isp,foreignIp)t5  
ON t1.timeStamp=t5.timeStamp 
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(foreignPort) AS 'foreignPortCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort)t6  
ON t1.timeStamp=t6.timeStamp 
JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(foreignGeo) AS 'foreignGeoCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
) c  
GROUP BY timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo)t7  
ON t1.timeStamp=t7.timeStamp JOIN 
(SELECT timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection,COUNT(infection) AS 'infectionCount' 
FROM (
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', port AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', "" AS 'infection'  
    FROM tbl_shadowserver_bot_geo 
    UNION ALL 
    SELECT date_format(timestamp, '%Y-%m-%d %h') AS 'timeStamp', ip AS 'localIp', "" AS 'localPort', "" AS 'localGeo', "" AS 'isp', "" AS 'foreignIp', "" AS 'foreignPort', "" AS 'foreignGeo', Formatreport AS 'infection'  
    FROM tbl_www_cymru_com 
    ) c  
    GROUP BY timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection)t8 
ON t1.timeStamp=t8.timeStamp ORDER BY timeStamp,localIp,localPort,localGeo,isp,foreignIp,foreignPort,foreignGeo,infection
4

1 に答える 1

1

ここでこの答えが何をするのかを明確にするために、私は最初にあなたの質問を私自身の言葉で言い換えようとします。2つのテーブルの和集合の各レコードに対して、結果セットに1つの行が必要です。その行には追加情報が含まれている必要があります。選択した列の特定のセットについて、選択したすべての列の現在の行と一致する入力からの行をカウントします。各ステップで、選択した行のセットに追加します。したがって、最初に同じタイムスタンプを持つすべての行をカウントします。次に、同じタイムスタンプと同じIPアドレスを持つすべての行をカウントします。等々。

同じテーブルの結合から繰り返し選択するので、短い名前を導入するのが賢明かもしれません。を作成するVIEWことでこれを行うことができます。次に、そのビューを参加の最初の要素として使用します。これにより、入力の行ごとに1行の出力が得られます。追加された統計については、行をカウントするサブクエリに参加し、そのカウントに対して選択されたすべての列でグループ化します。これらの選択されたすべての列を使用して、そのサブクエリを残りのクエリに結合します。したがって、たとえば:

CREATE VIEW view_both_tables AS
SELECT date_format(timestamp, '%Y-%m-%d %h') AS `timeStamp`, ip AS localIp, …
FROM tbl_shadowserver_bot_geo 
UNION ALL 
SELECT date_format(timestamp, '%Y-%m-%d %h') AS `timeStamp`, ip AS localIp, …
FROM tbl_www_cymru_com;

SELECT t0.*,
 t1.countSameTime,
 t2.countSameTimeAndLocalIp,
 t3.countSameTimeLocalIpAndInfection
FROM view_both_tables t0
LEFT JOIN (
  SELECT `timeStamp`,
   COUNT(*) AS `countSameTime`
  FROM view_both_tables
  GROUP BY `timeStamp`
 ) t1 USING (`timeStamp`)
LEFT JOIN (
  SELECT `timeStamp`, localIp,
   COUNT(*) AS `countSameTimeAndLocalIp`
  FROM view_both_tables
  GROUP BY `timeStamp`, localIp
 ) t2 USING (`timeStamp`, localIp)
LEFT JOIN (
  SELECT `timeStamp`, localIp, infection,
   COUNT(*) AS `countSameTimeLocalIpAndInfection`
  FROM view_both_tables
  GROUP BY `timeStamp`, localIp, infection
 ) t3 USING (`timeStamp`, localIp, infection)
;

このクエリは私のSQLフィドルから取得されました。他の列には例のデータが含まれていなかったため、選択した列は3つまでしかカバーされていません。これから、アイデアが明確になるはずです。

COUNT(*)一般に、特定の1つの列を数えるよりも効率的です。唯一の例外は、カウントする列にカウントNULLから省略すべき値が含まれている可能性がある場合、またはを使用している場合ですCOUNT(DISTINCT …)。しかし、あなたの質問の私の解釈は行ではなくレコードのカウントに言及しているので、これらの例外はどちらも当てはまりません。

スタイルに関する追加の注意として、列名を引用するために一重引用符を使用すると、SQLスタイルがかなり混乱します。通常、文字列は一重引用符を使用して区切られ、列はバッククォートを使用します。あなたが書いたのはデフォルトのMySQL構成の有効な構文ですが、それでも混乱を招きます。

パフォーマンスが問題になる場合は、を使用して単一のクエリを実行してみてくださいGROUP BY … WITH ROLLUP。結果を一時テーブルに保存すると、そのテーブルをそれ自体に繰り返し結合することで、要求した結果を導き出すことができます。パフォーマンスが向上するかどうかはわかりませんが、試してみる価値があるかもしれません。

于 2012-11-12T06:29:35.773 に答える