0

クエリから重複する値をフィルタリングする際に問題が発生しました。これは私の質問です

SELECT  cid.IDS_NO,cid.SUB_TITLE,cid.E_SUB_NAME, (cid.SUB_TITLE || ' '|| cid.E_SUB_NAME),
(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE)) 
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1), 
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1),
('COUNTRY' ||' ' || pl_post),pl_post 
FROM SUBSCRIBER cid where pl_postal_district = 15 and rownum < 3001 
and hi_property_type IN ('CONDO','COMMERCIAL BUILDING');

これらは私が問題を抱えている部分です:

(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE)) 
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1), 
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1);

これらの部分は常に複数のレコードを取得します。シーケンス番号が最も小さいレコードを1つだけ取得したいので、次のようにしました。

(SELECT(INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME FROM street_table where street_code = d.INST_ST_CODE)) 
FROM del d where d.IDS_NO = cid.IDS_NO and ROWNUM = 1 ORDER BY d.SEQ_NO DESC), 
(SELECT INST_ST_LEVEL || '-' || INST_STUNIT FROM detail d where d.IDS_NO = cid.IDS_NO and rownum = 1 ORDER BY d.SEQ_NO DESC);

しかし、括弧がないというエラーが常に表示されますが、で注文を削除すると、正常に機能します。クエリを正しく実行するにはどうすればよいですか?

4

2 に答える 2

3

読みやすくするためにクエリをフォーマットすることは、最初から大いに役立ちます。

しかし、あなたはまた、かなりトリッキーな問題を抱えています。

シーケンス番号が最小のレコードを1つだけ取得したい。

このように動作するはずです:

SELECT s.ids_no
      ,s.sub_title
      ,s.e_sub_name
      ,(s.sub_title || ' '|| s.e_sub_name) AS title_sub_name
      ,d.some_col_name
      ,t.inst_name
      ,('COUNTRY' ||' ' || s.pl_post) AS country_post
      ,s.pl_post
FROM   subscriber s

LEFT   JOIN (
   SELECT d.ids_no
         ,(d.inst_blk_hse || ' ' || st.e_street_name) AS some_col_name
         ,ROW_NUMBER() OVER (PARTITION BY d.ids_no ORDER BY d.seq_no) AS rn
   FROM   del d
   LEFT   JOIN e_street_name st ON st.street_code = d.inst_st_code
   ) d ON d.ids_no = s.ids_no AND d.rn = 1

LEFT   JOIN (
   SELECT ids_no
         ,(inst_st_level || '-' || inst_stunit)  AS inst_name
         ,ROW_NUMBER() OVER (PARTITION BY d.ids_no ORDER BY d.seq_no) AS rn
   FROM   detail         
   ) t ON t.ids_no = s.ids_no AND t.rn = 1


WHERE  s.pl_postal_district = 15
AND    s.rownum < 3001 
AND    s.hi_property_type IN ('CONDO','COMMERCIAL BUILDING');

この関連する質問の下でサブクエリがどのように機能するかについての詳細:
各GROUP BYグループの最初の行を選択しますか?

コア機能はROW_NUMBER()、シーケンス番号が最も小さいレコードを取得することです。
相関するサブクエリを書き直しました。これは、一般的にパフォーマンスの面で問題があるためです。それらも読みにくいです。
私はを使用LEFT JOINしているので、サブクエリが一致するものを見つけられない場合に備えて、行を取得します。

于 2013-01-20T10:15:35.647 に答える
1

サブクエリは1行のみを返す必要があります。したがってrownum = 1、サブクエリ内にあるサブクエリに追加する必要がありますFROM del d。何かのようなもの:

SELECT  
  cid.IDS_NO,
  cid.SUB_TITLE,
  cid.E_SUB_NAME, 
  (cid.SUB_TITLE || ' '|| cid.E_SUB_NAME),
  (SELECT (INST_BLK_HSE || ' ' || (SELECT E_STREET_NAME 
                                   FROM street_table 
                                   where street_code = d.INST_ST_CODE
                                     and rownum = 1)) <<<<<<< here
   FROM del d 
   where d.IDS_NO = cid.IDS_NO 
     and ROWNUM = 1), 
  (SELECT INST_ST_LEVEL || '-' || INST_STUNIT 
   FROM detail d 
   where d.IDS_NO = cid.IDS_NO 
   and rownum = 1),
  ('COUNTRY' ||' ' || pl_post),
  pl_post 
FROM SUBSCRIBER cid 
where pl_postal_district = 15 
  and rownum < 3001 
  and hi_property_type IN ('CONDO','COMMERCIAL BUILDING');

または、JOIN次のようなすべてのテーブル:

SELECT
  cid.IDS_NO,
  cid.SUB_TITLE,
  cid.E_SUB_NAME, 
  cid.SUB_TITLE || ' '|| cid.E_SUB_NAME,
  d.INST_BLK_HSE || ' ' || s.E_STREET_NAME, 
  d.INST_ST_LEVEL || '-' || d.INST_STUNIT 
  'COUNTRY' ||' ' || pl_post),
  pl_post 
FROM SUBSCRIBER cid 
INNER JOIN del          d ON d.IDS_NO      = cid.IDS_NO 
INNER JOIN detail      d2 ON d2.IDS_NO     = cid.IDS_NO 
INNER JOIN street_table s ON s.street_code = d.INST_ST_CODE
WHERE cid.pl_postal_district = 15 
  and cid.rownum < 3001 
  and cid.hi_property_type IN ('CONDO','COMMERCIAL BUILDING')
  and s.rownum = 1
  and d.rownum = 1
  and d2.rownum = 1;
于 2013-01-20T09:55:36.997 に答える