0

私はこのようなテーブルを持っています:

  +----+-----------+---------+
  | ID | monday    | tuesday | 
  +---+-----------+----------+
  |  1 | 1,2,3,4,5 | 3,4,5,6 |
  |  2 | 3,4,5     | 5,6,7   |
  +----+-----------+---------+

ここmondayで、およびtuesdayはSETタイプの列です。各数値は、特定の曜日の1時間の可用性を表します。最も多くの回答者がいつ空いているかを確認できるように、1時間ごとに利用可能なエントリの数を数えたいと思います。

たとえば、ではmonday、3のカウントは2になり、、の場合tuesday、3のカウントは1になります。できるだけ少ないクエリを使用したいと思います。

私はこれに何時間も取り組んできましたが、理解できません。どんな助けでもいただければ幸いです!これをより良くする方法についての提案もいただければ幸いです。ありがとう!!

4

1 に答える 1

0

@PRPGFerretが示唆しているように、スキーマを正規化する必要があります(@ BillKarwinの「データベース列にコンマ区切りのリストを格納するのは本当に悪いですか?に対する回答を参照してください)。

CREATE TABLE Hours (Hour TINYINT UNSIGNED NOT NULL);
INSERT INTO Hours (Hour) VALUES
  ( 0),( 1),( 2),( 3),( 4),( 5),( 6),( 7),( 8),( 9),(10),(11),
  (12),(13),(14),(15),(16),(17),(18),(19),(20),(21),(22),(23)
;

CREATE TABLE HoursAvailable (
  Day  ENUM(
         'Monday',
         'Tuesday',
         'Wednesday',
         'Thursday',
         'Friday',
         'Saturday',
         'Sunday'
       ) NOT NULL,
  ID   BIGINT  UNSIGNED NOT NULL,
  Hour TINYINT UNSIGNED NOT NULL,
  PRIMARY KEY (Hour, Day, ID)
);

INSERT INTO HoursAvailable (Day, ID, Hour)
  SELECT 'Monday', ID, Hour
  FROM   my_table JOIN Hours ON FIND_IN_SET(Hours.Hour, my_table.monday)
UNION ALL
  SELECT 'Tuesday', ID, Hour
  FROM   my_table JOIN Hours ON FIND_IN_SET(Hours.Hour, my_table.tuesday)
;

DROP TABLE Hours;
DROP TABLE my_table;

次に、次のことができます。

SELECT Day, COUNT(*) FROM HoursAvailable WHERE Hour = 3 GROUP BY Day;

sqlfiddleでそれを参照してください。

この方法でデータを正規化しないと、かなり非効率的なことを行う可能性があります。

SELECT SUM(FIND_IN_SET(3, monday )>0),
       SUM(FIND_IN_SET(3, tuesday)>0)
FROM   my_table;

sqlfiddleでそれを参照してください。

@ArielChelsăuによって観察されたように、火曜日は質問で言及された1ものではなく、のカウントを持っていることに注意してください。0

于 2012-12-15T11:07:21.013 に答える