2016-04-14 11 views
0

PostgreSQLで特定の条件を満たす最も一般的な値を見つける方法がわかりました。 IDは本のID番号であり、繰返し番号は本の複数のコピーがあることを意味します。最も一般的な条件での値の検索

私はここで2つのテーブルがあります:私は必要なもの

Table A: 
=====+=================== 
ID | Condition 
------------------------- 
1 | Taken 
1 | 
1 | Taken 
1 | 
2 | Taken 
3 | Taken 
3 | 
3 | Taken 
3 | Taken 
4 | 
4 | Taken 
etc. 

Table B: 
=====+=================== 
ID | Name 
------------------------- 
1 | BookA 
2 | BookB 
3 | BookC 
4 | BookD 
etc. 

は、単に最もコピーを取った本を見つけると、単純に本の名前をプリントアウトすることです。この場合、必要なものは次のとおりです。

問題は、各個人IDにどのくらいの本があるかを見つける方法を見つけることができないということです。私は一時テーブルを使ってみました:

CREATE TEMP TABLE MostCommon AS 
    (SELECT ID 
    FROM TableA 
    WHERE SUM(CASE WHEN Condition>0 then 1 else 0 END) 
    ) 
    SELECT NAME FROM TableB, MostCommon WHERE 
    MostCommon.ID = TableB.ID; 

しかし、それはエラーを投げるか、単に私に必要なものを与えません。どんな助けでも大歓迎です。

+0

はデータが作りますも意味ない;完全に同一の複数のレコードがあることは、どういう意味ですか?同じスキーマとデータを取得するために実行できるSQLコードの[最小限で完全で検証可能な例](https://stackoverflow.com/help/mcve)を投稿してください。 – bignose

+0

@bignose "ID"番号は本のIDです。それぞれのコピーが複数あるため、最初のテーブルでID番号が何度も繰り返されます。 – Anstane

答えて

1

オクラホマので、まず私はあなたがduble引用符を使用しなければならないことを意味しているあなたの列および表名は大文字と小文字が区別されていることを想定。 「撮影した」部数で最も「撮影した」ブックの名前を印刷するには、あなたが簡単なaggragete count()を使用することができ、その後、出力降下を注文し、最後に同じように、1行に出力を制限します。

SELECT 
    b."ID", 
    b."Name", 
    count(*) as takenCount 
FROM "TableA" a 
    JOIN "TableB" b ON a."ID" = b."ID" 
WHERE a."Condition" = 'Taken' 
GROUP BY b."ID", b."Name" 
ORDER BY 3 DESC 
LIMIT 1; 
+1

ありがとうございます。これは最も分かりやすく分かりやすい答えでした。そして、それは実際に動作します。 – Anstane

0
CREATE TEMP TABLE MostCommon AS 
(SELECT id, (sum(ID)/id) book_taken FROM tableA where condition = 'Taken' group by id); 


select name from tableB t2 join MostCommon mc on mc.id = t2.id where mc.id in (select max(book_taken) from MostCommon) 
0

データを賢明にする(すなわち、重複しない)ためには、スキーマを少し変更する必要があります。

CREATE TABLE book_condition (
    created TIMESTAMP, 
    book_id INTEGER, 
    condition VARCHAR, 
    PRIMARY KEY (created, book_id)); 

INSERT INTO book_condition (created, book_id, condition) 
VALUES 
    ('2016-01-01 08:30', 1, 'Taken'), 
    ('2016-01-01 08:35', 1, ''), 
    ('2016-01-01 08:40', 1, 'Taken'), 
    ('2016-01-01 08:45', 1, ''), 
    ('2016-01-01 08:50', 2, 'Taken'), 
    ('2016-01-01 08:55', 3, 'Taken'), 
    ('2016-01-01 09:00', 3, ''), 
    ('2016-01-01 09:05', 3, 'Taken'), 
    ('2016-01-01 09:10', 3, 'Taken'), 
    ('2016-01-01 09:15', 4, ''), 
    ('2016-01-01 09:20', 4, 'Taken'); 

CREATE TABLE book (
    book_id INTEGER, 
    name VARCHAR, 
    PRIMARY KEY (book_id)); 

INSERT INTO book (book_id, name) 
VALUES 
    (1, 'BookA'), 
    (2, 'BookB'), 
    (3, 'BookC'), 
    (4, 'BookD'); 

その後、質問はに分解:今までに撮影されたどのように多くの各書籍のコピー

  • total_taken値でレコードをランク​​付けする方法
SELECT 
    book_id, 
    COUNT(book_id) AS total_taken 
FROM book_condition 
WHERE 
    condition = 'Taken' 
GROUP BY book_id 
; 
book_id | total_taken 
---------+------------- 
     1 |   2 
     2 |   1 
     3 |   3 
     4 |   1 
(4 rows) 
  • book_id | total_taken | total_taken_rank 
    ---------+-------------+------------------ 
         3 |   3 |    1 
         1 |   2 |    2 
         2 |   1 |    3 
         4 |   1 |    3 
    (4 rows) 
    
    SELECT 
        book_id, 
        total_taken, 
        RANK() OVER (
         ORDER BY total_taken DESC 
         ) AS total_taken_rank 
    FROM (
        SELECT 
         book_id, 
         COUNT(book_id) AS total_taken 
        FROM book_condition 
        WHERE 
         condition = 'Taken' 
        GROUP BY book_id 
        ) AS bt 
    ORDER BY total_taken_rank ASC 
    ; 
    
    どのようにそのキー( id)値を含むクエリ結果に書籍の名前を取得するには?
SELECT 
    b.book_id, 
    b.name, 
    bt.total_taken, 
    RANK() OVER (
     ORDER BY bt.total_taken DESC 
     ) AS total_taken_rank 
FROM 
    book AS b 
    LEFT JOIN (
     SELECT 
      book_id, 
      COUNT(book_id) AS total_taken 
     FROM book_condition 
     WHERE 
      condition = 'Taken' 
     GROUP BY book_id 
     ) AS bt 
     USING (book_id) 
ORDER BY 
    total_taken_rank ASC, 
    book_id ASC 
; 
book_id | name | total_taken | total_taken_rank 
---------+-------+-------------+------------------ 
     3 | BookC |   3 |    1 
     1 | BookA |   2 |    2 
     2 | BookB |   1 |    3 
     4 | BookD |   1 |    3 
(4 rows) 
  • どのように結果だけで最高ランクのレコードを取得するには?
SELECT 
    br.book_id, 
    br.name, 
    br.total_taken 
FROM (
    SELECT 
     b.book_id, 
     b.name, 
     bt.total_taken, 
     RANK() OVER (
      ORDER BY bt.total_taken DESC 
      ) AS total_taken_rank 
    FROM 
     book AS b 
     LEFT JOIN (
      SELECT 
       book_id, 
       COUNT(book_id) AS total_taken 
      FROM book_condition 
      WHERE 
       condition = 'Taken' 
      GROUP BY book_id 
      ) AS bt 
      USING (book_id) 
    ) AS br 
WHERE 
    total_taken_rank = 1 
; 
book_id | name | total_taken 
---------+-------+------------- 
     3 | BookC |   3 
(1 row)