2

私は次のSQLを持っています:

SELECT `table1`.`value`, `table2`.* 
FROM `table2` 
INNER JOIN `table1` ON `table2`.`product_id` = `table1`.`entity_id`
WHERE `table2`.`created_at` > '2012-04-23' and 
(`table1`.`value` = 264 OR `table1`.`value` = 260)
order by order_id

次のような結果セットを返します (これは返された結果の一部にすぎません)。

value  order_id   ...
260    1234
260    1235
260    1236
264    1236
260    1237
260    1238
260    1239
264    1239
264    1240
260    1241

私が欲しいのは、これらの結果を取得し、order_id に値 260 と 264 の両方が含まれる注文のみを返すクエリです。この例に基づいて、探している最終結果は次のとおりです。

260   1236
264   1236
260   1239
264   1239

私の考えでは、これはサブセットで実行できますが、それを達成するための詳細については正確にはわかりません.

4

4 に答える 4

5

これは、関係分割で実現できます。

select r.order_id from (
  select 
    dividend.*  
  from your_table_or_query as dividend  -- assumes no duplicates in `dividend`; use `distinct` if there are any
  inner join divisor
  on dividend.value = divisor.value
) as r
group by r.order_id
having count(*) = (select count(*) from divisor);

結果:

+----------+
| order_id |
+----------+
|     1236 |
|     1239 |
+----------+
2 rows in set (0.00 sec)

クエリの場所your_table_or_query

select 260 as value from dual union select 264 as value from dual

ですdivisor

これにより、注文 ID 1236 および 1239 が返されます。その後join、元のクエリに編集して、必要に応じてそれらの注文 ID を持つすべての行を取得できます。


挿入ステートメントを含む完全なクエリ:

create table divisor (value int);
insert into divisor values (260), (264);

create table your_table_or_query (value int, order_id int);
insert into your_table_or_query values (260, 1234), (260, 1235), (260, 1236), (264, 1236), (260, 1237), (260, 1238), (260, 1239), (264, 1239), (264, 1240), (260, 1241);


select y.* from (
  select r.order_id from (
    select
      dividend.*
    from your_table_or_query as dividend
    inner join divisor
      on dividend.value = divisor.value
  ) as r 
  group by r.order_id
  having count(*) = (select count(*) from divisor)
) as quotient
inner join your_table_or_query y
  on quotient.order_id = y.order_id;

結果:

+-------+----------+
| value | order_id |
+-------+----------+
|   260 |     1236 |
|   264 |     1236 |
|   260 |     1239 |
|   264 |     1239 |
+-------+----------+
4 rows in set (0.00 sec)
于 2012-05-07T17:26:44.683 に答える
1

これはどう?

SELECT table1.value, table2.* 
FROM table2 
INNER JOIN table1 
ON table2.product_id = table1.entity_id
WHERE table2.created_at > '2012-04-23' AND
(table1.value = 264 OR table1.value = 260)
AND table2.order_id IN (
    SELECT table2.order_id  
    FROM table2 
    INNER JOIN table1 
    ON table2.product_id = table1.entity_id
    WHERE table2.created_at > '2012-04-23' AND
    (table1.value = 264 OR table1.value = 260)
    GROUP BY table2.order_id
    HAVING COUNT(*) = 2
)

(アポストロフィを省略して申し訳ありませんが、このフィールドのmysql要件はわかりません。この構文はms-sqlに準拠しています)

于 2012-05-07T17:14:39.303 に答える
1

これは、値 260 と 264 の両方を持つ注文のリストを返します - 値ごとに重複した結果ではなく、この結果だけが必要な場合:

SELECT `table2`.* 
FROM `table2` 
INNER JOIN `table1` as `table1_264`
  ON `table2`.`product_id` = `table1_264`.`entity_id`
  AND `table1_264`.`value` = 264
INNER JOIN `table1` as `table1_260`
  ON `table2`.`product_id` = `table1_260`.`entity_id`
  AND `table1_260`.`value` = 260
WHERE `table2`.`created_at` > '2012-04-23'
order by order_id


または、誰かがコストのかかるhaving句なしでより高速なソリューションを必要としている場合 (+ もちろん、クエリを保存するか、単に繰り返す代わりに CTE を使用できます)

SELECT 264 as `value`, `table2`.* 
 FROM `table2` 
 INNER JOIN `table1` as `table1_264` ON `table2`.`product_id` = `table1_264`.`entity_id` AND `table1_264`.`value` = 264
 INNER JOIN `table1` as `table1_260` ON `table2`.`product_id` = `table1_260`.`entity_id` AND `table1_260`.`value` = 260
 WHERE `table2`.`created_at` > '2012-04-23'
UNION ALL
SELECT 260, `table2`.* 
 FROM `table2` 
 INNER JOIN `table1` as `table1_264` ON `table2`.`product_id` = `table1_264`.`entity_id` AND `table1_264`.`value` = 264
 INNER JOIN `table1` as `table1_260` ON `table2`.`product_id` = `table1_260`.`entity_id` AND `table1_260`.`value` = 260
 WHERE `table2`.`created_at` > '2012-04-23'
order by order_id
于 2012-05-07T18:02:42.383 に答える
-1
SELECT `table1`.`value`, `table2`.* 
FROM `table1` 
LEFT JOIN `table2` ON `table1`.`entity_id` = `table2`.`product_id`
WHERE
(`table1`.`value` = 264 OR `table1`.`value` = 260)
AND `table2`.`created_at` > '2012-04-23' 
ORDER BY `table2`.order_id

左結合なので、table1.value の結果のみが一致し、他のテーブルからの情報は除外されます

于 2012-05-07T17:04:23.923 に答える