30

サブクエリ内とサブクエリの結果のテーブルの両方で、いくつかのサブクエリと多数の結合を含むSQLクエリを作成しています。

ビューを使用していないので、それは問題外です。

それを書いた後、私はそれを見て、それが何をしているのかと頭を悩ませています。

このような混乱を解消するために、どのようなフォーマットを使用していますか?おそらくインデント?

4

11 に答える 11

20

大規模なクエリでは、を使用して名前付きの結果セットに大きく依存する傾向がありますWITH。これにより、結果セットを事前に定義でき、メインクエリが簡単になります。名前付きの結果セットは、クエリプランをより効率的にするのに役立つ場合があります。たとえば、postgresは結果セットを一時テーブルに格納します。

例:

WITH 
  cubed_data AS (
     SELECT 
        dimension1_id,
        dimension2_id,
        dimension3_id,
        measure_id,
        SUM(value) value
     FROM
        source_data
     GROUP BY
        CUBE(dimension1, dimension2, dimension3),
        measure
  ), 
  dimension1_label AS(
     SELECT 
        dimension1_id,
        dimension1_label
     FROM 
        labels 
     WHERE 
        object = 'dimension1'
  ), ...
SELECT 
  *
FROM  
  cubed_data
  JOIN dimension1_label USING (dimension1_id)
  JOIN dimension2_label USING (dimension2_id)
  JOIN dimension3_label USING (dimension3_id)
  JOIN measure_label USING (measure_id)

この例は少し工夫されていますが、インラインサブクエリと比較して明確さが向上していることを示していると思います。名前付きの結果セットは、OLAPで使用するためのデータを準備しているときに非常に役立ちました。再帰クエリを作成する必要がある場合は、名前付き結果セットも必要です。

WITH少なくとも現在のバージョンのPostgres、Oracle、SQLServerで動作します

于 2011-03-28T16:01:19.380 に答える
10

少年はこれが質問の誤謬です。:)このサイトには賢い人がいるのと同じくらい、それを正しく行う方法はたくさんあります。そうは言っても、複雑なSQLステートメントを作成するときに私が正気を保つ方法は次のとおりです。

select
    c.customer_id
   ,c.customer_name
   ,o.order_id
   ,o.order_date
   ,o.amount_taxable
   ,od.order_detail_id
   ,p.product_name
   ,pt.product_type_name
from
    customer c
inner join
    order o
    on c.customer_id = o.customer_id
inner join
    order_detail od
    on o.order_id = od.order_id
inner join
    product p
    on od.product_id = p.product_id
inner join
    product_type pt
    on p.product_type_id = pt.product_type_id
where
    o.order_date between '1/1/2011' and '1/5/2011'
and
    (
        pt.product_type_name = 'toys'
     or
        pt.product_type_name like '%kids%'
    )
order by
    o.order_date
   ,pt.product_type_name
   ,p.product_name

興味があれば、挿入、更新、削除、相関サブクエリ、複雑な結合述語のレイアウトを投稿/送信できます。

これはあなたの質問に答えますか?

于 2011-03-28T16:53:39.837 に答える
4

一般に、人々は予約語の行を区切り、サブクエリをインデントします。

SELECT *
FROM tablename
WHERE value in
   (SELECT *
   FROM tablename2 
   WHERE condition)
ORDER BY column
于 2011-03-28T15:47:40.790 に答える
4

テーブルのエイリアスと単純な一貫性により、長い道のりを歩むことができます

きちんと見えるのは、メインキーワードSELECT、FROM、WHERE(など)の改行です。

結合は難しい場合があります。結合のON部分をインデントすると、その重要な部分が前面に表示されます。

同じレベルで複雑な論理式(結合と条件の両方)を壊すことも役立ちます。

論理的に同じレベルのステートメントをインデントする(サブクエリ、開き角かっこなど)

すべてのキーワードと標準機能を大文字にします。

本当に複雑なSQLはコメントを敬遠することはありませんが、通常、これらは動的SQLではなくSQLスクリプトに含まれています。

編集例:

SELECT a.name, SUM(b.tax)
FROM   db_prefix_registered_users a 
       INNER JOIN db_prefix_transactions b 
           ON a.id = b.user_id
       LEFT JOIN db_countries
           ON b.paid_from_country_id = c.id
WHERE  a.type IN (1, 2, 7) AND
       b.date < (SELECT MAX(date) 
                 FROM audit) AND
       c.country = 'CH'

したがって、最後に要約すると、一貫性が最も重要です。

于 2011-03-28T15:47:59.963 に答える
3

一般に、私はフォーマット規則の単純な階層セットに従います。基本的に、SELECT、FROM、ORDERBYなどのキーワードはすべて独自の行に配置されます。各フィールドは(再帰的に)独自の行になります

SELECT 
    F.FIELD1,
    F.FIELD2,
    F.FIELD3
FROM
    FOO F 
WHERE 
    F.FIELD4 IN 
    (
        SELECT 
            B.BAR
        FROM 
            BAR B
        WHERE
            B.TYPE = 4
            AND B.OTHER = 7
    )
于 2011-03-28T15:49:34.040 に答える
3

私は次のようなものを使用するのが好きです:

SELECT    col1,
          col2,
          ...
FROM
    MyTable as T1
INNER JOIN
    MyOtherTable as T2
        ON t1.col1 = t2.col1
        AND t1.col2 = t2.col2
LEFT JOIN
    (   
        SELECT 1,2,3
        FROM Someothertable
        WHERE somestuff = someotherstuff
    ) as T3
    ON t1.field = t3.field
于 2011-03-28T15:49:42.317 に答える
3

SQLをフォーマットする唯一の正しい正しい方法は次のとおりです。

SELECT t.mycolumn        AS column1
      ,t.othercolumn     AS column2
      ,SUM(t.tweedledum) AS column3
FROM   table1 t
      ,(SELECT u.anothercol
              ,u.memaw                  /*this is a comment*/
        FROM   table2       u
              ,anothertable x
        WHERE  u.bla       = :b1        /*the bla value*/
        AND    x.uniquecol = :b2        /*the widget id*/
       ) v
WHERE  t.tweedledee = v.anothercol
AND    t.hohum      = v.memaw
GROUP BY t.mycolumn
        ,t.othercolumn
HAVING COUNT(*) > 1
;

;)

真剣に、しかし、私は非常に複雑なSQLクエリを飼いならすために(すでに提案されているように)WITH句を使用するのが好きです。

于 2011-03-29T04:59:44.127 に答える
2

うわー、ここにはたくさんの回答がありますが、私があまり見たことがないのはコメントです!特に大きなSQLステートメントでは、全体に多くのコメントを追加する傾向があります。フォーマットは重要ですが、適切に配置された意味のあるコメントは、あなただけでなく、コードを維持する必要のある貧しい人々にとっても非常に重要です;)

于 2011-03-29T11:04:44.307 に答える
2

視覚化しやすいようにビューに配置します。ドキュメントの一部としてスクリーンショットを保持することもできます。ビューを保存したり、他の目的に使用したりする必要はありません。

于 2011-03-28T15:49:07.730 に答える
2

確かにインデントしますが、サブクエリをコメントで分割し、エイリアス名を本当に意味のあるものにし、それらが参照するサブクエリ(innerCustomer、outerCustomerなど)を指定することもできます。

共通テーブル式は、場合によってはクエリを意味のあるセクションに分割するのに役立ちます。

于 2011-03-28T15:51:00.257 に答える
2

何千もの意見があり、正しい答えが1つもない、昔からの質問であり、私のお気に入りの1つです。これが私の2セントです。

サブクエリに関しては、最近、「極端な」インデントと次のようなコメントの追加で何が起こっているのかを追跡する方が簡単であることがわかりました。

SELECT mt.Col1, mt.Col2, subQ.Dollars
 from MyTable1 mt
  inner join (--  Get the dollar total for each SubCol
              select SubCol, sum(Dollars) Dollars
               from MyTable2
               group by SubCol) subQ
   on subQ.SubCol = mt.Col1
 order by mt.Col2

他のセントについては、最初の単語に大文字のみを使用します。実行中のクエリのページを使用すると、新しいクエリが開始されたときにそれを見つけるのが少し簡単になります。

もちろん、マイレージは異なります。

于 2011-03-28T16:09:22.993 に答える