2

私はサブクエリを初めて使用し、次の状況でサブクエリが必要だと思いますが、どのように進めるかがわかりません。

次のクエリがあります。ここで、クエリに追加する必要があるものが2つあります=

  • CAの消費者の場合、自動車事故(car_acc)は1回しか発生しませんが、他の州では問題ありません。
  • FL、MD、NH、およびWAでは、現在保険がかけられているのは0(ブール値)ですが、他の州では1のみである必要があります。

    SELECT Count(*),
           Avg(sl.our_cost),
           Avg(sl.purchase_price)
    FROM   sold_leads AS sl
           INNER JOIN leads AS l
                   ON l.id = sl.lead_id
           INNER JOIN contacts AS c
                   ON c.lead_id = l.id
           INNER JOIN drivers AS d
                   ON d.lead_id = l.id
    WHERE  c.state IN( 'AK', 'AL', 'AR', 'AZ',
                       'CA', 'CO', 'CT', 'DC',
                       'DE', 'FL', 'GA', 'HI',
                       'IA', 'ID', 'IL', 'IN',
                       'KS', 'KY', 'LA', 'MD',
                       'ME', 'MI', 'MN', 'MO',
                       'MS', 'MT', 'NC', 'ND',
                       'NE', 'NH', 'NJ', 'NM',
                       'NV', 'NY', 'OH', 'OK',
                       'OR', 'PA', 'RI', 'SC',
                       'SD', 'TN', 'TX', 'UT',
                       'VA', 'VT', 'WA', 'WI',
                       'WV', 'WY' )
           AND l.leg = 0
           AND ( Datediff(CURRENT_DATE, d.date_of_birth) / 365 ) >= 50
           AND l.create_date >= '2012-1-1';  
    

これらのサブクエリをクエリに追加するにはどうすればよいですか?その情報を見つけるためのより良い方法はありますか?

編集:

私はそれが1つの「自動車事故」または「違反」を読むべきだったことに言及する必要があります。私は自動車事故と違反の2つの異なるテーブルを持っているので、CAの居住者の場合、1つの事故または1つの違反のある人だけが必要です。

4

2 に答える 2

1

のデータは別々のテーブルにあるため、car_accidentsviolations使用してそれらを結合する必要がありますleft join

これが理にかなっていることを願っています:-)

SELECT Count(*),
       Avg(sl.our_cost),
       Avg(sl.purchase_price)
FROM   sold_leads AS sl
       INNER JOIN leads AS l
               ON l.id = sl.lead_id
       INNER JOIN contacts AS c
               ON c.lead_id = l.id
       INNER JOIN drivers AS d
               ON d.lead_id = l.id
       LEFT JOIN 
  (SELECT ca1.driver_id, COUNT(*) AS cnt FROM car_accidents ca1 GROUP BY ca1.driver_id) ca 
               ON (c.state = 'CA' and ca.driver_id = d.id)
       LEFT JOIN 
  (SELECT v1.driver_id, COUNT(*) AS cnt FROM violations v1 GROUP BY v1.driver_id) v
               ON (c.state IN ('CA') and v.driver_id = d.id)
WHERE  c.state IN( 'AK', 'AL', 'AR', 'AZ','CA', 'CO', 'CT', 'DC',
                   'DE', 'FL', 'GA', 'HI','IA', 'ID', 'IL', 'IN',
                   'KS', 'KY', 'LA', 'MD','ME', 'MI', 'MN', 'MO',
                   'MS', 'MT', 'NC', 'ND','NE', 'NH', 'NJ', 'NM',
                   'NV', 'NY', 'OH', 'OK','OR', 'PA', 'RI', 'SC',
                   'SD', 'TN', 'TX', 'UT','VA', 'VT', 'WA', 'WI',
                   'WV', 'WY' )
       AND l.leg = 0
       AND ( Datediff(CURRENT_DATE, d.date_of_birth) / 365 ) >= 50
       AND l.create_date >= '2012-1-1'
       AND IFNULL(v.cnt,0) < 2 AND ifnull(ca.cnt.0) < 2
       AND (c.state IN ('FL','MD','NH','WA') OR c.IsInsured = 1) 

状態を別のテーブルに含める方がはるかに理にかなっています。そうすれば、契約条件をそのテーブルに入れて、結合基準で使用できます。

Table state
-----------
id : varchar(2) primary key not null
country : varchar(45) not null
max_accidents : int null
max_violations : int null
must_be_insured : boolean not null

次に、クエリを次のように書き直すことができます。

SELECT Count(*),
       Avg(sl.our_cost),
       Avg(sl.purchase_price)
FROM   sold_leads AS sl
       INNER JOIN leads AS l
               ON l.id = sl.lead_id
       INNER JOIN contacts AS c
               ON c.lead_id = l.id
       INNER JOIN drivers AS d
               ON d.lead_id = l.id
       INNER JOIN state s ON (s.id = c.state)
       LEFT JOIN 
(SELECT ca1.driver_id, COUNT(*) AS cnt FROM car_accidents ca1 GROUP BY ca1.driver_id) ca 
           ON (s.max_accidents IS NOT NULL AND ca.driver_id = d.id)
   LEFT JOIN 
(SELECT v1.driver_id, COUNT(*) AS cnt FROM violations v1 GROUP BY v1.driver_id) v
           ON (s.max_violations IS NOT NULL AND v.driver_id = d.id)
       AND l.leg = 0
       AND (Datediff(CURRENT_DATE, d.date_of_birth) / 365.25 ) >= 50
       AND l.create_date >= '2012-1-1'; 
       AND IFNULL(v.cnt,0) < 2 AND ifnull(ca.cnt.0) < 2
       AND (s.must_be_insured = 0 OR c.IsInsured = 1)
于 2013-01-28T17:57:03.187 に答える
0

サブクエリと同じではないことは知っていますが、この「サブコンディション」の問題をCASEステートメントで解決することがよくあります。WHERE句の最後に1つ追加できます。

WHERE c.state IN (...)
    AND l.leg = 0
    AND ( Datediff(CURRENT_DATE, d.date_of_birth) / 365 ) >= 50
    AND l.create_date >= '2012-1-1'
    AND CASE 
        # Identify cases where record should be excluded
        WHEN c.state = 'CA' AND c.car_acc > 1   THEN 0
        WHEN c.state NOT IN ('FL', 'MD', 'NH', 'WA') AND c.currently_insured = 1   THEN 0
        ELSE 1
    END = 1

警告:他のフィルタリングアプローチと比較して、これがパフォーマンスにどのように影響するかはわかりません。

于 2013-01-28T17:57:21.847 に答える