0

私は1つのテーブル(A)に1つのものを持ち、別のテーブル(MC)からのcategory_idを他の2つ(C1、C2)に分類しています。

特定のカテゴリで提示されたものの数を数えたいと思います。

ライブデータの例:

テーブルA

main_key (unique)    stuff_id (non unique)
   1                    7
   2                    6 
   3                    3

表 C1

category_id main_key (it is FK for A table)
   1             1
   1             2
   3             1

表 C2

category_id main_key (it is FK for A table)
   2             3
   2             1

テーブルMC

category_id category_name
   1             blablbl
   2               asas
   3             asasa
...

間の関係: C1 と A の数対 1 C2 と A の数対 1 C1 または C2 と MC の数対 1

現在の例では、最終結果を次のように表示したいと思います

stuff_qnt        category_id        category_name
2                   1                  blablbl
2                   2                   asas
1                   3                   asasa

単一のクエリでそれを達成するにはどうすればよいですか?

私のクエリは次のとおりです。

SELECT count(A.stuff_id) as stuff_qnt, MC.category_id, MC.category_name 
FROM A
LEFT JOIN C1 using(main_key)
LEFT JOIN C2 using(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id AND C2.category_id = MC.category_id)
GROUP BY C1.category_id, C2.category_id

しかし、間違った結果が表示されます。何が間違っていますか?

4

3 に答える 3

1

このリファレンスをご覧ください。

クエリ:

select m.category_id, m.category_name, count(a.stuff_id) as cntstuff from
(select * from c1 
 union all
 select * from c2) as c
join a 
on a.main_key = c.main_key
join mc m
on m.category_id = c.category_id
group by m.category_id
order by m.category_id
;

結果:

CATEGORY_ID     CATEGORY_NAME   CNTSTUFF
1               blablbl         2
2               asas            2
3               asasa           1
于 2012-12-12T13:41:09.820 に答える
1
SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
  FROM MC
  JOIN (SELECT C1.Category_ID
          FROM A
          JOIN C1 ON A.Main_Key = C1.Main_Key
        UNION ALL
        SELECT C2.Category_ID
          FROM A
          JOIN C2 ON A.Main_Key = C2.Main_Key
       ) AS C
    ON C.Category_ID = MC.Category_ID
 GROUP BY C.Category_ID, MC.Category_Name
 ORDER BY C.Category_ID, Stuff_Qnt;

A を C1 と結合したカテゴリと、A を C2 と結合したカテゴリが必要であり、LEFT OUTER JOIN で得られるようなデカルト積は絶対に必要ないため、カテゴリ ID のリストの UNION を取得します。 、次に集約して MC と結合します。

CREATE TABLE A
(
    main_key INTEGER NOT NULL PRIMARY KEY,
    stuff_id INTEGER NOT NULL
);
INSERT INTO A VALUES(1, 7);
INSERT INTO A VALUES(2, 6);
INSERT INTO A VALUES(3, 3);

CREATE TABLE MC
(
    category_id INTEGER NOT NULL PRIMARY KEY,
    category_name VARCHAR(10) NOT NULL
);
INSERT INTO mc VALUES(1, "blablbl");
INSERT INTO mc VALUES(2, "asas");
INSERT INTO mc VALUES(3, "asasa");

CREATE TABLE C1
(
    category_id INTEGER NOT NULL REFERENCES mc,
    main_key INTEGER NOT NULL REFERENCES a
);
INSERT INTO c1 VALUES(1, 1);
INSERT INTO c1 VALUES(1, 2);
INSERT INTO c1 VALUES(3, 1);

CREATE TABLE C2
(
    category_id INTEGER NOT NULL REFERENCES mc,
    main_key INTEGER NOT NULL REFERENCES a
);
INSERT INTO c2 VALUES(2, 3);
INSERT INTO c2 VALUES(2, 1);

SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
  FROM MC
  JOIN (SELECT C1.Category_ID
          FROM A
          JOIN C1 ON A.Main_Key = C1.Main_Key
        UNION ALL
        SELECT C2.Category_ID
          FROM A
          JOIN C2 ON A.Main_Key = C2.Main_Key
       ) AS C
    ON C.Category_ID = MC.Category_ID
 GROUP BY C.Category_ID, MC.Category_Name
 ORDER BY C.Category_ID, Stuff_Qnt;

出力:

2   1   blablbl
2   2   asas
1   3   asasa

これは、A に 2 つの余分な行を追加し、C1 と C2 に対応する行を追加したテストです。私のクエリとdkkumargoyalによるクエリの 2 つのクエリがテストされています。

CREATE TABLE A(main_key INTEGER NOT NULL PRIMARY KEY, stuff_id INTEGER NOT NULL);
INSERT INTO A VALUES(1, 7);
INSERT INTO A VALUES(2, 6);
INSERT INTO A VALUES(3, 3);
INSERT INTO A VALUES(4, 3);
INSERT INTO A VALUES(5, 3);

CREATE TABLE MC(category_id INTEGER NOT NULL PRIMARY KEY, category_name VARCHAR(10) NOT NULL);
INSERT INTO mc VALUES(1, "blablbl");
INSERT INTO mc VALUES(2, "asas");
INSERT INTO mc VALUES(3, "asasa");

CREATE TABLE C1(category_id INTEGER NOT NULL REFERENCES mc, main_key INTEGER NOT NULL REFERENCES a);
INSERT INTO c1 VALUES(1, 1);
INSERT INTO c1 VALUES(1, 2);
INSERT INTO c1 VALUES(3, 1);
INSERT INTO c1 VALUES(3, 4);
INSERT INTO c1 VALUES(1, 4);
INSERT INTO c1 VALUES(1, 5);

CREATE TABLE C2(category_id INTEGER NOT NULL REFERENCES mc, main_key INTEGER NOT NULL REFERENCES a);

INSERT INTO c2 VALUES(2, 3);
INSERT INTO c2 VALUES(2, 1);
INSERT INTO c2 VALUES(2, 5);

SELECT COUNT(*) AS Stuff_Qnt, C.Category_ID, MC.Category_Name
  FROM MC
  JOIN (SELECT C1.Category_ID
          FROM A
          JOIN C1 ON A.Main_Key = C1.Main_Key
        UNION ALL
        SELECT C2.Category_ID
          FROM A
          JOIN C2 ON A.Main_Key = C2.Main_Key
       ) AS C
    ON C.Category_ID = MC.Category_ID
 GROUP BY C.Category_ID, MC.Category_Name
 ORDER BY C.Category_ID, Stuff_Qnt;

-- Query by dkkumargoyal
SELECT COUNT(DISTINCT A.stuff_id) AS stuff_qnt, MC.category_id, MC.category_name 
FROM A
LEFT JOIN C1 on a.main_key = c1.main_key  -- USING(main_key)
LEFT JOIN C2 on a.main_key = c2.main_key  -- USING(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id OR C2.category_id = MC.category_id)
GROUP BY MC.category_id, mc.category_name
ORDER BY MC.Category_id, stuff_qnt;       -- stuff_qnt added for standard compatibility

テスト DBMS (Informix 11.70.FC6) でコードを動作させるには、変更が必要でした。

結果 1:

4   1   blablbl
3   2   asas
2   3   asasa

結果 2:

3   1   blablbl
2   2   asas
2   3   asasa

私の結果は正しいと思いますが、他の結果はそうではないと思います。これは主A.Stuff_IDに、質問が一意ではないことを規定している場合に代替手段が一意であることに依存しているためです (そして、データの行が追加されると一意ではなくなります)。

于 2012-12-12T13:03:47.343 に答える
0

このSQLを試してください。

SELECT COUNT(DISTINCT A.stuff_id) AS stuff_qnt, MC.category_id, MC.category_name 
FROM A
LEFT JOIN C1 USING(main_key)
LEFT JOIN C2 USING(main_key)
LEFT JOIN MC ON (C1.category_id = MC.category_id OR C2.category_id = MC.category_id)
GROUP BY MC.category_id
于 2012-12-12T13:18:08.087 に答える