1

PHP ベースの Web ソフトウェアを構築しようとしていますが、ソリューションの構文がわからない問題に遭遇しました。

基本的に、私は2つのテーブルを持っています:

+-------------+     +---------------+
| Certs       |     | Clients       |
+-------------+     +---------------+
| userID      |     | eID           |
| prodID      |     | prods         |
| prodName    |     +---------------+
+-------------+

ここでは、個人が購入するすべての製品は、その個人の一意の userID と製品の一意の prodID によって保存されます。

クライアントは、異なる ID を持つ売り手と、コンマで区切られた製品 ID の文字列である製品のようなものです。

certs テーブルの行の例は次のようになります。

userID  |  prodID  |  prodName
------------------------------
9000    |  42      |  Pen     
4234    |  54      |  Pencil
9000    |  54      |  Pencil

クライアント行の​​例は次のようになります。

eID  |  prods
-------------
595  |  42,54

ここで、特定の販売者のすべての製品を購入したすべてのユーザー ID を返すクエリを作成する必要があります。

たとえば、売り手 ID 595 の場合、userID 9000 は 42 と 54 の両方を購入したため、9000 を返す必要があります。

テーブル構造は便宜上変更できますが、他の技術的な理由により、販売者に関連付けられた製品の正規化されたリストを作成することはできません.

どんな助けでも大歓迎です!ありがとう〜

注: 別の言い方をすれば、売り手の商品のリストを結果型の配列に保持することです。次に、SELECT prodID FROM certs WHERE userID = x そして最後に、prodID の結果配列に配列 prod のすべての要素があるかどうかを確認します。

4

1 に答える 1

2

この解決策を試してください:

SELECT a.userID
FROM certs a
INNER JOIN clients b ON b.eID = 595 AND FIND_IN_SET(a.prodID, b.prods) > 0
CROSS JOIN
(
    SELECT (LENGTH(prods) - LENGTH(REPLACE(prods, ',', ''))) + 1 AS prodcnt
    FROM clients
    WHERE eID = 595
) c
GROUP BY a.userID, c.prodcnt
HAVING COUNT(1) = c.prodcnt

使い方:

CROSS JOIN
(
    SELECT (LENGTH(prods) - LENGTH(REPLACE(prods, ',', ''))) + 1 AS prodcnt
    FROM clients
    WHERE eID = 595
) c

これが行うことは、特定の販売者が持っている prodID の数を各行に追加することです。CSV リストの文字列の長さを取得し、同じ CSV リストの長さをカンマなしで引き、その差に 1 を加えて計算します。例:

" "の文字列の長さ54,234,436は 10 です。

コンマを置き換えます。

" "の文字列の長さ54234436は 8 です。

したがって、(10-8)+1 = 3 です。

リスト内の 3 つの項目。


FIND_IN_SETの結合条件としてを使用して、CSVリスト内に が存在するかどうかを判断します。certsclientsprodIDprods

FIND_IN_SET基本的に、CSV リスト内の特定の項目の 1 から始まるインデックス位置を返します。例えば:

FIND_IN_SET('54', '34,76,54,128') 

リストの 3 番目の項目として存在する3ため、返されます。54結合条件のリスト内に存在するかどうかのみを確認する必要があるため、> 0 かどうかを確認するだけです。アイテムが CSV リストにない場合は、0 が返されます。


特定のクライアントのデカルト結合された製品数とテーブルが結合されると、中間結果セットは次のようになります。

a.userID  |  a.prodID  |  b.eID  |  b.prods  |  c.prodcnt
---------------------------------------------------------
9000      |  42        |  595    |  42,54    |  2
4234      |  54        |  595    |  42,54    |  2
9000      |  54        |  595    |  42,54    |  2

これらの各行は、結合条件を満たしました。

次に、 ごとにグループ化して、userIDごとの行数をカウントしますuserID。9000 の行数は の繰り返し値と同じであるためc.prodcnt、その行が返されます。4234結合条件を満たした行が 1 つしかないため、userIDは除外されます。

于 2012-07-23T06:18:53.047 に答える