3

「市場で入手可能な」製品と「まだ開発中」の製品を 2 つの別々のテーブル (market_productdev_product) に格納するデータベースがあります。3 番目の表 (物質) には、製品を構成するすべての物質が含まれています。他の 2 つの表 (marked_product_compおよびdev_product_comp) は、製品構成を保持します。

市販品と同じ成分で開発中の商品を選びたい。

次の (簡略化された) 例では、クエリは dev_product テーブルから ID = 2 の製品を選択する必要があります。

CREATE table market_product (ID SERIAL PRIMARY KEY);
CREATE table dev_product (ID SERIAL PRIMARY KEY);
CREATE table substance (ID SERIAL PRIMARY KEY);
CREATE table market_product_comp (prodID SERIAL, substID SERIAL, PRIMARY KEY(prodID,substID));
CREATE table dev_product_comp (devID SERIAL, substID SERIAL, PRIMARY KEY(devID,substID));

INSERT INTO market_product VALUES (1),(2);
INSERT INTO dev_product VALUES (1),(2);
INSERT INTO substance VALUES (1),(2),(3);
INSERT INTO market_product_comp VALUES (1,1),(1,2),(2,3);
INSERT INTO dev_product_comp VALUES (1,2),(2,1),(2,2);

そのようなクエリを書く方法は?


アップデート:

申し訳ありませんが、あいまいな方法で質問したことに気づいていませんでした。

少なくとも 1 つの市販製品と同じ組成を持つ開発中の製品を選択したい。例えば、dev_product物質 {1,2} でできた があり、物質 {1,2,3} でできた が 1 つしかない場合、それは組成が異なるためmarket_product破棄したいと思います。dev_productこれが明確になることを願っています。

4

4 に答える 4

1

COUNT()これは、 NULL を無視するという事実に依存するソリューションです。

SELECT d1.devId, m1.prodId
FROM market_product_comp m1
CROSS JOIN dev_product_comp d1
LEFT OUTER JOIN dev_product_comp d2 
   ON (d2.substId = m1.substId AND d1.devId = d2.devId)
LEFT OUTER JOIN market_product_comp m2 
   ON (d1.substId = m2.substId AND m1.prodId = m2.prodId)
GROUP BY d1.devId, m1.prodId
HAVING COUNT(d1.substId) = COUNT(d2.substId)
   AND COUNT(m1.substId) = COUNT(m2.substId);

これを MySQL 5.0.75 でテストしましたが、すべて ANSI 標準 SQL であるため、どのブランドの SQL データベースでも動作するはずです。

于 2009-09-09T05:01:08.287 に答える
0

MySQL

SELECT  *
FROM    dev_product dp
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    market_product mp
        WHERE   NOT EXISTS
                (
                SELECT  NULL
                FROM    dev_product_comp dpc
                WHERE   dpc.prodID = dp.id
                        AND NOT EXISTS
                        (
                        SELECT  NULL
                        FROM    market_product_comp mpc
                        WHERE   mpc.prodID = mp.id
                                AND mpc.substID = dpc.substID
                        )
                )
                AND NOT EXISTS
                (
                SELECT  NULL
                FROM    market_product_comp mpc
                WHERE   mpc.prodID = mp.id
                        AND NOT EXISTS
                        (
                        SELECT  NULL
                        FROM    dev_product_comp dpc
                        WHERE   dpc.prodID = dp.id
                                AND dpc.substID = mpc.substID
                        )
                )

        )

PostgreSQL

SELECT  *
FROM    dev_product dp
WHERE   EXISTS
        (
        SELECT  NULL
        FROM    market_product mp
        WHERE   NOT EXISTS
            (
            SELECT  NULL
            FROM    (
                SELECT  substID
                FROM    market_product_comp mpc
                WHERE   mpc.prodID = mp.ID
                ) m
            FULL OUTER JOIN
                (
                SELECT  substID
                FROM    dev_product_comp dpc
                WHERE   dpc.devID = dp.ID
                ) d
            ON  d.substID = m.substID
            WHERE   d.substID IS NULL OR m.substID IS NULL
            )
        )

これらのクエリではどちらも を使用していませんCOUNT(*)。ペア全体の評価を停止するには、一致しないコンポーネントを 1 つだけ見つけるだけで十分です。

説明については、私のブログの次のエントリを参照してください。

于 2009-09-08T18:49:37.823 に答える
0
select d.* from dev_product d
 left join dev_product_comp dpc on d.Id = dpc.devId
where dpc.substID in 
  (select mpc.substID from market_product_comp  mpc 
    left join market_product mp on mp.Id = mpc.prodId)
于 2009-09-08T15:18:06.217 に答える
0

すべての製品物質が市場製品で使用されている開発製品 ID のみを選択します。

select 
   dp.id
from 
   dev_product dp
   inner join dev_product_comp dpc on dp.id = dpc.devid
where 
   dpc.substid in (select substid from market_product_comp) 
group by 
   dp.id
having 
   count() = (select count() from dev_product_comp where devid = dp.id)

生産に使用されていない成分を含む製品は除外されます。

于 2009-09-08T15:25:37.360 に答える