3

クエリから出力する必要があるものの正しい構文を理解するのに苦労しています。

これが私のデータです (いいえ、これらは正しい列名ではありません。読みやすくしようとしています) 取得している実際のテーブルには 26 列のデータがあります。

employeeNumber - recordNumber - job                - dept - type
 12            - 1            - stapler            - 788  - s
 12            - 6            - paper pusher       - 400  - s
 18            - 2            - phone cleaner      - 600  - p
 18            - 4            - sweeper            - 567  - s
 19            - 0            - typist             - 400  - s
 21            - 0            - mouse ball cleaner - 400  - p

したがって、選択ルールは次のとおりです。
タイプが P の場合、そのレコードを選択します
従業員に P レコードがない場合は、S を選択します
従業員に複数の S レコードがある場合は、より低いレコード番号を選択するか、部門が 400 ではないレコードを選択します (400 行) Sレコードが 1 つしかなく、Dept が 400 の場合、行が返されます

これは現在機能しているものです:

SELECT employeeNumber, recordNumber, job, dept, type
FROM employees
WHERE (type = 'P')
 OR
 (type = 'S'
            AND employeeNumber NOT IN
                (
                  SELECT employeeNumber
                  FROM employees
                  WHERE type = 'P'
                )
)
ORDER BY employeeNumber, recordNumber

そして、私がやりたいことは、最後に「limit = 1」(または同様のもの)を配置することです。これにより、複数の S 行の場合、より低い recordNumber が返される行になります。

上記のデータから返されるレコード セットは次のとおりです。

employeeNumber - recordNumber - job                - dept - type
 12            - 1            - stapler            - 788  - s
 18            - 2            - phone cleaner      - 600  - p
 19            - 0            - typist             - 400  - s
 21            - 0            - mouse ball cleaner - 400  - p

泥のように透明ですよね?

エラーが発生し続けます。私が見逃している「簡単な」方法はありますか?

ご協力いただきありがとうございます。

ミシェル

4

2 に答える 2

1

私はこの部分をよく理解していません:

下位のレコード番号を選択するか、部門が 400 ではないレコードを選択します (400 行は常に上位のレコード番号になります)。

(「400 行が常に上位のレコード番号になる」場合は、OR の左側で十分です)

ただし、これは出発点です。(OR の後にその部分を却下しました)

SELECT * FROM (
    SELECT employeeNumber, recordNumber, job, dept, type
    rank() over (partition by employeeNumber order by type, recordNumber) as rnk
    FROM employees
)
WHERE type = 'P' or (rnk=1 and type=S)
于 2011-12-29T15:50:06.180 に答える
0

データがemployeNumber内に重複するTYPEおよびrecordNumber値を持つことができない場合、@ Florinの答えは機能します。そうしないと、分析関数の ORDER BY によって同じランクの 2 つの行が生成される可能性が少しでもあると、重複する行が再び得られます。代わりに ROW_NUMBER を使用し、WHERE 句を単純化して、行番号 1 のすべての行を単純に選択することができます (@Florin のクエリでも同様に実行できます)。

CREATE TABLE employees (employeeNumber INTEGER, recordNumber INTEGER
           , job VARCHAR2(100), dept INTEGER, TYPE VARCHAR2(2));

INSERT INTO employees VALUES (12, 6, 'paper pusher', 400, 'S');
INSERT INTO employees VALUES (18, 2, 'phone cleaner', 600, 'P');
INSERT INTO employees VALUES (18, 4, 'sweeper', 567, 'S');
INSERT INTO employees VALUES (19, 0, 'typist', 400, 'S');
INSERT INTO employees VALUES (21, 0, 'mouse ball cleaner', 400, 'P');
INSERT INTO employees VALUES (12, 1, 'stapler', 788, 'S');
INSERT INTO employees VALUES (12, 1, 'stapler2', 654, 'S');

SELECT employeeNumber, recordNumber, job, dept, type
  FROM (SELECT employeeNumber, recordNumber, job, dept, type
             , ROW_NUMBER() 
                 OVER (PARTITION BY employeeNumber 
                           ORDER BY type, recordNumber) rn
          FROM employees)
 WHERE rn = 1;

これをもたらします:

EMPLOYEENUMBER  RECORDNUMBER JOB                   DEPT TYPE
-------------- ------------- -------------------- ----- ----
            12             1 stapler                788 S
            18             2 phone cleaner          600 P
            19             0 typist                 400 S
            21             0 mouse ball cleaner     400 P

このデータで RANK を使用すると、従業員 12 に対して 2 行が得られます。もちろん、これが発生しない場合は、クエリでその事実を報告する必要があります。

于 2011-12-30T16:22:02.900 に答える