0

現在、次のSQLステートメントがあります

MySQL クエリ:

SELECT
    c.day,
    COUNT(*)
FROM
    calendar c
JOIN
    visitors d
ON  DAYOFMONTH(d.created) = c.day
WHERE
    c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
AND
    site_id = 16
GROUP BY
    DAYOFMONTH(d.created)
ORDER BY
    DAYOFMONTH(d.created)

マイ テーブル:

Calendar

id  | day
---------
1   | 1
2   | 2
3   | 3
...
31  | 31

Visitors

id  | site_id | created
-----------------------------------
1   | 16      | 2012-10-18 11:14:39
2   | 16      | 2012-10-18 11:15:17
3   | 11      | 2012-10-18 11:49:14
4   | 11      | 2012-10-18 11:49:43
5   | 16      | 2012-10-19 11:54:37
6   | 1       | 2012-10-19 05:56:31
7   | 2       | 2012-10-19 05:57:56

この回答で規定されているようにテーブル、カレンダーを作成しましたが、それでも同じ情報が得られるようです。データがある日付のみを取得しています。

day    |   COUNT(*)
---------------------
18     |   2
19     |   1

0データのない日付も取得する必要があります。

アップデート:

I tried this:
SELECT *
FROM calendar c
LEFT JOIN visitors d
ON  DAYOFMONTH(d.created) = c.day

SELECT *
FROM calendar c
LEFT JOIN visitors d
ON  DAYOFMONTH(d.created) = c.day
WHERE  site_id = 16

site_id = 16は確かに結果を殺しているものであることを確認できます.

4

3 に答える 3

1

LEFT JOINの代わりに使用INNER JOIN

SELECT ...
FROM   calendar c 
       LEFT JOIN  visitors d
         ON DAYOFMONTH(d.created) = c.day
WHERE...

INNER JOIN他のテーブルで少なくとも 1 つの一致がある行のみを取得し、左側のLEFT JOINテーブルで定義されているすべての行を取得し、他のテーブルで一致するかどうかに関係なく検索します。

更新 1

SELECT  c.day,
        COUNT(*)
FROM    calendar c
        LEFT JOIN
        (
            SELECT *
            FROM   visitors
            WHERE  site_id = 16
        ) d ON  DAYOFMONTH(d.created) = c.day
WHERE c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
GROUP BY DAYOFMONTH(c.day)
ORDER BY DAYOFMONTH(c.day)

**ソープ・オバジーによる更新

SELECT  c.day,
        COUNT(site_id)
FROM    calendar c
        LEFT JOIN
        (
            SELECT *
            FROM   visitors
            WHERE  site_id = 16
        ) d ON  DAYOFMONTH(d.created) = c.day
WHERE c.day BETWEEN DAYOFMONTH('2012-10-01') AND DAYOFMONTH('2012-10-31')
GROUP BY c.day
ORDER BY c.day

毎日COUNT(*)返すので使えません。また、 andで on c.day を1使用するべきではありません。これは、既に必要なものであるためです。DAYOFMONTHGROUP BYORDER BY

于 2012-10-22T00:23:30.103 に答える
0

最後のポスターが言ったように、明確にするためにLEFT JOINを使用してください。

Calendar テーブルが左のテーブルで、Visitors テーブルが右のテーブルであるとします。

インナージョインあり

FROM Calendar c
INNER JOIN Visitors v
ON c.Date = v.Date

LEFT と RIGHT の両方で一致する必要があります。

左結合あり

FROM Calendar c
LEFT JOIN Visitors v
ON c.Date = v.Date

LEFT テーブル (Calendar) からすべてのレコードを返し、RIGHT テーブル (Visitors) から一致するレコードのみを返します。一致する Visitor データがないすべてのカレンダーの日付に対して NULL が残されます (もちろん、これを処理しない限り) COALESCEのようなもので)

右結合あり

FROM Calendar c
RIGHT JOIN Visitors v
ON c.Date = v.Date

右のテーブル (Visitor) からすべてのレコードを返し、左のテーブル (Calendar) から一致するレコードのみを返します。一致が見つからなかった列の値には NULLS が含まれます。日付が Calendar テーブルにない場合。

それが役立つことを願っています。

ケビン

于 2012-10-22T00:36:17.883 に答える
0

これに答える別の提案は、

WHERE site_id = 16

たとえば、JOINに

SELECT
 c.[Day]
,COUNT(v.[id])
FROM TestDB.dbo.Calendar c
LEFT JOIN TestDB.dbo.Visitor v
ON c.[Day] = DATEPART(d,v.Created)
AND v.[SiteID] = 16
GROUP BY c.[Day]
ORDER BY c.[Day]

個人的には派生テーブルを使用するのは好きではありません。よりネイティブな結合を使用するとパフォーマンスが大幅に向上することがわかったからです。ただし、通常は数百万行のデータセットで作業します。

于 2012-10-22T01:27:10.733 に答える