5

各ユーザーが互いに「5」以内に行を持っている回数を数えたいと思います。

たとえば、Don - 501 と Don - 504 はカウントする必要がありますが、Don - 501 と Don - 1600 はカウントしないでください。

始める:

Name        value
_________   ______________
Don         1235
Don         6012
Don         6014
Don         6300
James       9000
James       9502
James       9600
Sarah       1110
Sarah       1111
Sarah       1112
Sarah       1500
Becca       0500
Becca       0508
Becca       0709

終了:

Name            difference_5
__________      _____________
Don             1
James           0
Sarah           2
Becca           0
4

4 に答える 4

2

サブクエリの自己結合と組み合わせて、ABS()関数を使用します。

だから、次のようなもの:

SELECT name, COUNT(*) / 2 AS difference_5
FROM (
  SELECT a.name name, ABS(a.value - b.value) 
  FROM  tbl a JOIN tbl b USING(name)
  WHERE ABS(a.value - b.value) BETWEEN 1 AND 5
) AS t GROUP BY name

アンドレアスのコメントに従って編集。

于 2012-08-01T16:21:02.120 に答える
1

name各->ペアが一意であると仮定すると、これにより、値が名前ごとvalueに5以内である回数が取得されます。

SELECT    a.name, 
          COUNT(b.name) / 2 AS difference_5
FROM      tbl a
LEFT JOIN tbl b ON a.name = b.name AND 
                   a.value <> b.value AND
                   ABS(a.value - b.value) <= 5
GROUP BY  a.name

お気づきのように、自分と等しいペアも除外する必要があります。

ただし、各名前の値がテーブル内の任意の値の5以内に入った回数をカウントする場合は、次を使用できます。

SELECT    a.name,
          COUNT(b.name) / 2 AS difference_5
FROM      tbl a
LEFT JOIN tbl b ON NOT (a.name = b.name AND a.value = b.value) AND
                   ABS(a.value - b.value) <= 5
GROUP BY  a.name

両方のソリューションについては、 SQLFiddleデモを参照してください。

于 2012-08-01T19:32:15.357 に答える
0

OP もゼロ カウントを必要とするため、セルフレフト ジョインが必要になります。1 人の人物がまったく同じ値を 2 つ持っている場合は、追加のロジックが必要です。これらも 1 回だけカウントする必要があります。

WITH cnts AS (
        WITH pair AS (
                SELECT t1.zname,t1.zvalue
                FROM ztable t1
                JOIN ztable t2
                ON t1.zname = t2.zname
                WHERE ( t1.zvalue < t2.zvalue
                        AND t1.zvalue >= t2.zvalue - 5 )
                OR (t1.zvalue = t2.zvalue AND t1.ctid < t2.ctid)
                )
        SELECT DISTINCT zname
        , COUNT(*) AS znumber
        FROM pair
        GROUP BY zname
        )
, names AS (
        SELECT distinct zname  AS zname
        FROM ztable
        GROUP BY zname
        )
SELECT n.zname
        , COALESCE(c.znumber,0) AS znumber
FROM names n
LEFT JOIN cnts c ON n.zname = c.zname
        ;

結果:

DROP SCHEMA
CREATE SCHEMA
SET
CREATE TABLE
INSERT 0 14
 zname | znumber 
-------+---------
 Sarah |       3
 Don   |       1
 Becca |       0
 James |       0
(4 rows)

注: CTE については申し訳ありませんが、mysql タグは見たことがありませんでした。問題が気に入っただけです ;-)

于 2012-08-01T16:48:15.737 に答える
0
SELECT
    A.Name,
    SUM(CASE WHEN (A.Value < B.Value) AND (A.Value >= B.Value - 5) THEN 1 ELSE 0 END) Difference_5
FROM
    tbl A INNER JOIN
    tbl B USING(Name)
GROUP BY
    A.Name
于 2012-08-01T16:56:24.020 に答える